summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/tests/integration
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/general/tests/integration')
-rw-r--r--ansible_collections/community/general/tests/integration/targets/aix_filesystem/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_set_priority.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apk/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apk/tasks/main.yml160
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/tasks/main.yml65
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_rustup_cargo.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/tasks/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/action_plugins/_unsafe_assert.py56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/library/cmd_echo.py5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/test_cmd_echo.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/vars/main.yml139
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_incus/aliases6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_incus/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_incus/test_connection.inventory11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_auth_method.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_binding_rule.yml73
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_general.yml76
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_kv.yml57
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_policy.yml72
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_role.yml194
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_session.yml57
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_token.yml88
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/templates/consul_config.hcl.j25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/deploy_helper/tasks/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ejabberd_user/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ejabberd_user/handlers/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ejabberd_user/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml122
-rw-r--r--ansible_collections/community/general/tests/integration/targets/etcd3/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml122
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/reset_fs_uuid.yml59
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation_with_opts.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_counter/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml60
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_ini/vars/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_jc/aliases3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists/tasks/main.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists/vars/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_time/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml58
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_to_ini/vars/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/main.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_multi_value.yml79
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value_with_tilde.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_multi_value.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/files/gitconfig11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/error_handling.yml26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_all_values.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_multi_value.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_simple_value.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/main.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_file.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_global.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config_info/vars/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/tasks/main.yml221
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/tasks/main.yml606
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_issue/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_issue/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_issue/files/description.md9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_issue/tasks/main.yml150
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_label/README.md19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_label/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_label/defaults/main.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_label/tasks/main.yml463
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/defaults/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/files/description.md9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/tasks/main.yml129
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_milestone/README.md19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_milestone/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_milestone/defaults/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_milestone/tasks/main.yml388
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/tasks/main.yml221
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml92
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homectl/aliases2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/htpasswd/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/htpasswd/handlers/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/htpasswd/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/htpasswd/tasks/main.yml83
-rw-r--r--ansible_collections/community/general/tests/integration/targets/htpasswd/vars/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/00-basic.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/04-symlink.yml59
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/05-ignore_spaces.yml123
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/06-modify_inactive_option.yml123
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/07-section_name_spaces.yml103
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/tasks/main.yml58
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/02-partial-restore.yml66
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/aliases4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/files/setupSSLServer.py13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/tasks/state_change.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/handlers/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/tasks/main.yml72
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/readme.adoc2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license3
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml168
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/readme.adoc27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/tasks/main.yml567
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md20
-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.yml120
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/vars/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_component_info/README.md20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_component_info/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_component_info/tasks/main.yml266
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_component_info/vars/main.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/README.md21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/aliases4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/tasks/main.yml160
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/vars/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml113
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/readme.adoc27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/tasks/main.yml373
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/vars/main.yml48
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/README.md20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/tasks/main.yml233
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/vars/main.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user/README.md21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user/aliases4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user/tasks/main.yml114
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user/vars/main.yml46
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/auth.yml47
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/basic.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/pages.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/schema.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/listen_ports_facts/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/aliases2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/basic.yml102
-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.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/vars/main.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases1
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_all_hosts.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml52
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup_missing_pv.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown_missing_pv.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_change.yml163
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_create.yml71
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_pvresize.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_uuid_reset.yml107
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/main.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/setup.yml50
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/teardown.yml46
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/test.yml105
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/tasks/main.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/tasks/setup.yml57
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/tasks/teardown.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvol/tasks/test_pvs.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml171
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/aliases2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/osx_defaults/tasks/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/handlers/main.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/locally_installed_package.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/remove_nosave.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/yay-become.yml66
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2 (renamed from ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh)0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx_info/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pnpm/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pnpm/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pnpm/tasks/main.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pnpm/tasks/run.yml322
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pnpm/templates/package.j213
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox_pool/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox_pool/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox_pool/tasks/main.yml220
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox_template/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox_template/tasks/main.yml136
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/pagination.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_image_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_server_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/handlers/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Alpine.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Archlinux.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian-12.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/RedHat.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Suse.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/tasks/main.yml22
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/archlinux.yml5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/tasks/main.yml26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-12-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.3.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/shutdown/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml73
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml244
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test.yml235
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test_3dash.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml81
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test_dangerous.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/test_empty_list.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/aliases1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml94
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/aliases5
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.sh15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/fqdn_valid_1.yml58
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/vars/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/aliases2
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml9
328 files changed, 11226 insertions, 938 deletions
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
index 25146062d..878088f4e 100644
--- 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
@@ -90,7 +90,7 @@
size: -2G
state: present
-- name: Resizing /mksysb to 100G (no enought space)
+- name: Resizing /mksysb to 100G (not enough space)
aix_filesystem:
filesystem: /mksysb
size: +100G
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
index 46cf48e59..9bc523b0d 100644
--- 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
@@ -22,7 +22,7 @@
assert:
that:
- 'alternative is changed'
- - 'cmd.stdout == "dummy{{ item }}"'
+ - 'cmd.stdout == "dummy" ~ item'
- name: check that alternative has been updated
command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 60 + item|int }}' '{{ alternatives_dir }}/dummy'"
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
index 13655b194..297477ac9 100644
--- a/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases
@@ -4,5 +4,4 @@
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/apache2_module/tasks/actualtest.yml b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml
index 3301a16b1..6fd10ce57 100644
--- 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
@@ -73,7 +73,7 @@
state: absent
force: true
- - name: reenable autoindex
+ - name: re-enable autoindex
community.general.apache2_module:
name: autoindex
state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/apk/aliases b/ansible_collections/community/general/tests/integration/targets/apk/aliases
new file mode 100644
index 000000000..6e8c01586
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apk/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
+needs/root
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel
+skip/ubuntu \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/apk/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/apk/tasks/main.yml
new file mode 100644
index 000000000..0e1b0ae42
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apk/tasks/main.yml
@@ -0,0 +1,160 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2024, Max Maxopoly <max@dermax.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
+- name: Run apk tests on Alpine
+ when: ansible_distribution in ['Alpine']
+ block:
+ - name: Ensure vim is not installed
+ community.general.apk:
+ name: vim
+ state: absent
+
+ - name: Install vim
+ community.general.apk:
+ name: vim
+ state: present
+ register: results
+
+ - name: Ensure vim was installed
+ ansible.builtin.assert:
+ that:
+ - results is changed
+ - (results.packages | length) >= 1 # vim has dependencies, so depending on the base image this number may vary
+
+ - name: Install vim again
+ community.general.apk:
+ name: vim
+ state: present
+ register: results
+
+ - name: Ensure vim was not installed again
+ ansible.builtin.assert:
+ that:
+ - results is not changed
+ - (results.packages | default([]) | length) == 0
+
+ - name: Ensure vim is not installed
+ community.general.apk:
+ name: vim
+ state: absent
+ register: results
+
+ - name: Ensure vim was uninstalled
+ ansible.builtin.assert:
+ that:
+ - results is changed
+ - (results.packages | length) >= 1
+
+ - name: Install vim without cache
+ community.general.apk:
+ name: vim
+ state: present
+ no_cache: true
+ register: results
+
+ - name: Ensure vim was installed without cache
+ ansible.builtin.assert:
+ that:
+ - results is changed
+
+ - name: Install vim again without cache
+ community.general.apk:
+ name: vim
+ state: present
+ no_cache: true
+ register: results
+
+ - name: Ensure vim was not installed again without cache
+ ansible.builtin.assert:
+ that:
+ - results is not changed
+ - (results.packages | default([]) | length) == 0
+
+ - name: Ensure a bunch of packages aren't installed
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: absent
+
+ - name: Install a bunch of packages
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: present
+ register: results
+
+ - name: Ensure a bunch of packages were installed
+ ansible.builtin.assert:
+ that:
+ - results is changed
+ - (results.packages | length) >= 3
+
+ - name: Install a bunch of packages again
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: present
+ register: results
+
+ - name: Ensure a bunch of packages were not installed again
+ ansible.builtin.assert:
+ that:
+ - results is not changed
+ - (results.packages | default([]) | length) == 0
+
+ - name: Ensure a bunch of packages are not installed
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: absent
+ register: results
+
+ - name: Ensure a bunch of packages were uninstalled
+ ansible.builtin.assert:
+ that:
+ - results is changed
+ - (results.packages | length) >= 3
+
+ - name: Install a bunch of packages without cache
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: present
+ no_cache: true
+ register: results
+
+ - name: Ensure a bunch of packages were installed without cache
+ ansible.builtin.assert:
+ that:
+ - results is changed
+
+ - name: Install a bunch of packages again without cache
+ community.general.apk:
+ name:
+ - less
+ - nano
+ - vim
+ state: present
+ no_cache: true
+ register: results
+
+ - name: Ensure a bunch of packages were not installed again without cache
+ ansible.builtin.assert:
+ that:
+ - results is not changed
+ - (results.packages | default([]) | length) == 0
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
index 1c4f4d1aa..21b07038f 100644
--- a/ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml
@@ -29,7 +29,7 @@
that:
- archive_no_options is changed
- "archive_no_options.dest_state == 'archive'"
- - "{{ archive_no_options.archived | length }} == 3"
+ - "archive_no_options.archived | length == 3"
- name: Remove the archive - no options ({{ format }})
file:
@@ -54,7 +54,7 @@
that:
- archive_file_options_stat is not changed
- "archive_file_options.mode == '0600'"
- - "{{ archive_file_options.archived | length }} == 3"
+ - "archive_file_options.archived | length == 3"
- name: Remove the archive - file options ({{ format }})
file:
@@ -146,7 +146,7 @@
assert:
that:
- archive_path_list is changed
- - "{{ archive_path_list.archived | length }} == 3"
+ - "archive_path_list.archived | length == 3"
- name: Remove archive - path list ({{ format }})
file:
@@ -168,8 +168,8 @@
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"
+ - "(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:
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
index 8f0b8cff8..a7e151d25 100644
--- a/ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml
@@ -20,21 +20,28 @@
assert:
that:
- archive_remove_source_files is changed
- - "{{ archive_remove_source_files.archived | length }} == 3"
+ - "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"
+- name: Remove source files in check mode ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/{{ item }}"
+ state: absent
+ check_mode: true
with_items:
- foo.txt
- bar.txt
- empty.txt
+ register: remove_files
+
+- name: Assert that source files were removed - remove source files ({{ format }})
+ assert:
+ that:
+ - remove_files is not changed
- name: Copy source files - remove source directory ({{ format }})
copy:
@@ -76,17 +83,24 @@
assert:
that:
- archive_remove_source_directory is changed
- - "{{ archive_remove_source_directory.archived | length }} == 3"
+ - "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: Remove source source directory in check mode ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir"
+ state: absent
+ check_mode: true
+ register: remove_dir
+
- name: Verify source directory was removed - remove source directory ({{ format }})
assert:
that:
- - "'{{ remote_tmp_dir }}/tmpdir' is not exists"
+ - remove_dir is not changed
- name: Create temporary directory - remove source excluding path ({{ format }})
file:
@@ -120,7 +134,7 @@
assert:
that:
- archive_remove_source_excluding_path is changed
- - "{{ archive_remove_source_excluding_path.archived | length }} == 2"
+ - "archive_remove_source_excluding_path.archived | length == 2"
- name: Remove archive - remove source excluding path ({{ format }})
file:
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases
index 914c36ad3..f5b6800db 100644
--- a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases
@@ -1,4 +1,4 @@
-# Copyright (c) Ansible Projec
+# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/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/callback_default_without_diff/aliases b/ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/aliases
new file mode 100644
index 000000000..3e2dd244c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/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_default_without_diff/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/tasks/main.yml
new file mode 100644
index 000000000..5fc656e84
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/tasks/main.yml
@@ -0,0 +1,65 @@
+---
+####################################################################
+# 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 file
+ tempfile:
+ register: tempfile
+
+ - name: Run tests
+ include_role:
+ name: callback
+ vars:
+ tests:
+ - name: Basic file diff
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_DIFF_ALWAYS: 'true'
+ ANSIBLE_PYTHON_INTERPRETER: "{{ ansible_python_interpreter }}"
+ ANSIBLE_STDOUT_CALLBACK: community.general.default_without_diff
+ playbook: |
+ - hosts: testhost
+ gather_facts: true
+ tasks:
+ - name: Create file
+ copy:
+ dest: "{{ tempfile.path }}"
+ content: |
+ Foo bar
+
+ - name: Modify file
+ copy:
+ dest: "{{ tempfile.path }}"
+ content: |
+ Foo bar
+ Bar baz bam!
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Gathering Facts] *********************************************************",
+ "ok: [testhost]",
+ "",
+ "TASK [Create file] *************************************************************",
+ "changed: [testhost]",
+ "",
+ "TASK [Modify file] *************************************************************",
+ "changed: [testhost]",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 ",
+ ]
+
+ always:
+ - name: Clean up temp file
+ file:
+ path: "{{ tempfile.path }}"
+ state: absent
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
index bb22e27c0..29f27c3fd 100644
--- a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml
@@ -18,3 +18,5 @@
- import_tasks: test_version.yml
environment: "{{ cargo_environment }}"
when: has_cargo | default(false)
+- import_tasks: test_rustup_cargo.yml
+ when: rustup_cargo_bin | 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
index 232658ab4..7eec97ac4 100644
--- a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml
@@ -26,3 +26,17 @@
has_cargo: true
when:
- ansible_system == 'FreeBSD' and ansible_distribution_version is version('13.0', '>')
+
+- block:
+ - name: Download rustup
+ get_url:
+ url: https://sh.rustup.rs
+ dest: /tmp/sh.rustup.rs
+ mode: "0750"
+ force: true
+ - name: Install rustup cargo
+ command: /tmp/sh.rustup.rs -y
+ - set_fact:
+ rustup_cargo_bin: "{{ lookup('env', 'HOME') }}/.cargo/bin/cargo"
+ when:
+ - ansible_distribution != 'CentOS' or ansible_distribution_version is version('7.0', '>=')
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_rustup_cargo.yml b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_rustup_cargo.yml
new file mode 100644
index 000000000..ec2cf6e6d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_rustup_cargo.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: Install application helloworld
+ community.general.cargo:
+ executable: "{{ rustup_cargo_bin }}"
+ name: helloworld
+ register: rustup_install_absent_helloworld
+
+- name: Uninstall application helloworld
+ community.general.cargo:
+ executable: "{{ rustup_cargo_bin }}"
+ state: absent
+ name: helloworld
+ register: rustup_uninstall_present_helloworld
+
+- name: Check assertions helloworld
+ assert:
+ that:
+ - rustup_install_absent_helloworld is changed
+ - rustup_uninstall_present_helloworld is changed
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
index 40e762d68..2b67b5c17 100644
--- 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
@@ -8,6 +8,14 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Help debugging
+ debug:
+ msg: >-
+ distribution={{ ansible_distribution }},
+ distribution major version={{ ansible_distribution_major_version }},
+ os_family={{ ansible_os_family }},
+ Python version={{ ansible_python.version.major }}
+
- name: test cloud-init
# TODO: check for a workaround
# install 'cloud-init'' failed: dpkg-divert: error: `diversion of /etc/init/ureadahead.conf
@@ -15,10 +23,11 @@
# /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.
+ # (!= 42 and >= 15) as cloud-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_os_family == "Suse" and ansible_distribution_major_version|int == 15)
- 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
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/action_plugins/_unsafe_assert.py b/ansible_collections/community/general/tests/integration/targets/cmd_runner/action_plugins/_unsafe_assert.py
new file mode 100644
index 000000000..498e8258d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/action_plugins/_unsafe_assert.py
@@ -0,0 +1,56 @@
+# Copyright 2012, 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
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.errors import AnsibleError
+from ansible.playbook.conditional import Conditional
+from ansible.plugins.action import ActionBase
+
+
+class ActionModule(ActionBase):
+ ''' Fail with custom message '''
+
+ _requires_connection = False
+
+ _VALID_ARGS = frozenset(('msg', 'that'))
+
+ def _make_safe(self, text):
+ # A simple str(text) won't do it since AnsibleUnsafeText is clever :-)
+ return ''.join(chr(ord(x)) for x in text)
+
+ def run(self, tmp=None, task_vars=None):
+ if task_vars is None:
+ task_vars = dict()
+
+ result = super(ActionModule, self).run(tmp, task_vars)
+ del tmp # tmp no longer has any effect
+
+ if 'that' not in self._task.args:
+ raise AnsibleError('conditional required in "that" string')
+
+ fail_msg = 'Assertion failed'
+ success_msg = 'All assertions passed'
+
+ thats = self._task.args['that']
+
+ cond = Conditional(loader=self._loader)
+ result['_ansible_verbose_always'] = True
+
+ for that in thats:
+ cond.when = [str(self._make_safe(that))]
+ test_result = cond.evaluate_conditional(templar=self._templar, all_vars=task_vars)
+ if not test_result:
+ result['failed'] = True
+ result['evaluated_to'] = test_result
+ result['assertion'] = that
+
+ result['msg'] = fail_msg
+
+ return result
+
+ result['changed'] = False
+ result['msg'] = success_msg
+ return result
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
index cd8766264..ec0beb98e 100644
--- 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
@@ -21,11 +21,14 @@ from ansible_collections.community.general.plugins.module_utils.cmd_runner impor
def main():
module = AnsibleModule(
argument_spec=dict(
+ cmd=dict(type="str", default="echo"),
+ path_prefix=dict(type="str"),
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"),
+ tt=dict(),
),
supports_check_mode=True,
)
@@ -40,7 +43,7 @@ def main():
arg_formats[arg] = func(*args)
- runner = CmdRunner(module, ['echo', '--'], arg_formats=arg_formats)
+ runner = CmdRunner(module, [module.params["cmd"], '--'], arg_formats=arg_formats, path_prefix=module.params["path_prefix"])
with runner.context(p['arg_order'], check_mode_skip=p['check_mode_skip']) as ctx:
result = ctx.run(**p['arg_values'])
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/cmd_runner/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/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/cmd_runner/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml
index 36ab039f0..e955c5d3d 100644
--- 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
@@ -6,3 +6,4 @@
ansible.builtin.include_tasks:
file: test_cmd_echo.yml
loop: "{{ cmd_echo_tests }}"
+ when: item.condition | default(true) | bool
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
index 1c2caf2b5..a2a9fb8b7 100644
--- 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
@@ -3,17 +3,27 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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 }}]
+- name: create copy of /bin/echo ({{ item.name }})
+ ansible.builtin.copy:
+ src: /bin/echo
+ dest: "{{ item.copy_to }}/echo"
+ mode: "0755"
+ remote_src: true
+ when: item.copy_to is defined
+
+- name: test cmd_echo module ({{ item.name }})
cmd_echo:
- arg_formats: "{{ item.arg_formats|default(omit) }}"
+ cmd: "{{ item.cmd | default(omit) }}"
+ path_prefix: "{{ item.path_prefix | default(omit) }}"
+ 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) }}"
+ 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) }}"
+ check_mode: "{{ item.check_mode | default(omit) }}"
+ ignore_errors: "{{ item.expect_error | default(omit) }}"
-- name: check results [{{ item.name }}]
- assert:
+- name: check results ({{ item.name }})
+ _unsafe_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
index 7f0027d49..f9a715338 100644
--- 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
@@ -121,3 +121,142 @@ cmd_echo_tests:
- test_result.rc == None
- test_result.out == None
- test_result.err == None
+
+ - name: set aa and tt value
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --tt-arg potatoes\n"
+ - test_result.err == ""
+
+ - name: use cmd echo
+ cmd: echo
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --tt-arg potatoes\n"
+ - test_result.err == ""
+
+ - name: use cmd /bin/echo
+ cmd: /bin/echo
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --tt-arg potatoes\n"
+ - test_result.err == ""
+
+ # this will not be in the regular set of paths get_bin_path() searches
+ - name: use cmd {{ remote_tmp_dir }}/echo
+ condition: >
+ {{
+ ansible_distribution != "MacOSX" and
+ not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
+ }}
+ copy_to: "{{ remote_tmp_dir }}"
+ cmd: "{{ remote_tmp_dir }}/echo"
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --tt-arg potatoes\n"
+ - test_result.err == ""
+
+ - name: use cmd echo with path_prefix {{ remote_tmp_dir }}
+ cmd: echo
+ condition: >
+ {{
+ ansible_distribution != "MacOSX" and
+ not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
+ }}
+ copy_to: "{{ remote_tmp_dir }}"
+ path_prefix: "{{ remote_tmp_dir }}"
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --tt-arg potatoes\n"
+ - test_result.err == ""
+
+ - name: use cmd never-existed
+ cmd: never-existed
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ expect_error: true
+ assertions:
+ - >
+ "Failed to find required executable" in test_result.msg
+
+ - name: use cmd /usr/bin/never-existed
+ cmd: /usr/bin/never-existed
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ tt:
+ func: as_opt_val
+ args: [--tt-arg]
+ arg_order: 'aa tt'
+ arg_values:
+ tt: potatoes
+ aa: 11
+ expect_error: true
+ assertions:
+ - >
+ "No such file or directory" in test_result.msg
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_incus/aliases b/ansible_collections/community/general/tests/integration/targets/connection_incus/aliases
new file mode 100644
index 000000000..5a0c47032
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_incus/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_incus/runme.sh b/ansible_collections/community/general/tests/integration/targets/connection_incus/runme.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_incus/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_incus/test_connection.inventory b/ansible_collections/community/general/tests/integration/targets/connection_incus/test_connection.inventory
new file mode 100644
index 000000000..84b69faf7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_incus/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
+
+[incus]
+incus-pipelining ansible_ssh_pipelining=true
+incus-no-pipelining ansible_ssh_pipelining=false
+[incus:vars]
+ansible_host=ubuntu-2204
+ansible_connection=community.general.incus
+ansible_python_interpreter=python3
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_auth_method.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_auth_method.yml
new file mode 100644
index 000000000..611d67309
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_auth_method.yml
@@ -0,0 +1,74 @@
+---
+# Copyright (c) 2024, Florian Apolloner (@apollo13)
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 an auth method
+ community.general.consul_auth_method:
+ name: test
+ type: jwt
+ config:
+ jwt_validation_pubkeys:
+ - |
+ -----BEGIN PUBLIC KEY-----
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo
+ 4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u
+ +qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh
+ kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ
+ 0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg
+ cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc
+ mwIDAQAB
+ -----END PUBLIC KEY-----
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.auth_method.Type == 'jwt'
+ - result.operation == 'create'
+
+- name: Update auth method
+ community.general.consul_auth_method:
+ name: test
+ max_token_ttl: 30m80s
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.auth_method.Type == 'jwt'
+ - result.operation == 'update'
+
+- name: Update auth method (noop)
+ community.general.consul_auth_method:
+ name: test
+ max_token_ttl: 30m80s
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.auth_method.Type == 'jwt'
+ - result.operation is not defined
+
+- name: Delete auth method
+ community.general.consul_auth_method:
+ name: test
+ state: absent
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'remove'
+
+- name: Delete auth method (noop)
+ community.general.consul_auth_method:
+ name: test
+ state: absent
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.operation is not defined
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_binding_rule.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_binding_rule.yml
new file mode 100644
index 000000000..218daf982
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_binding_rule.yml
@@ -0,0 +1,73 @@
+---
+# Copyright (c) 2024, Florian Apolloner (@apollo13)
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 an auth method
+ community.general.consul_auth_method:
+ name: test
+ type: jwt
+ config:
+ jwt_validation_pubkeys:
+ - |
+ -----BEGIN PUBLIC KEY-----
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo
+ 4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u
+ +qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh
+ kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ
+ 0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg
+ cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc
+ mwIDAQAB
+ -----END PUBLIC KEY-----
+
+- name: Create a binding rule
+ community.general.consul_binding_rule:
+ name: test-binding
+ description: my description
+ auth_method: test
+ bind_type: service
+ bind_name: yolo
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.binding_rule.AuthMethod == 'test'
+ - result.binding.Description == 'test-binding: my description'
+ - result.operation == 'create'
+
+- name: Update a binding rule
+ community.general.consul_binding_rule:
+ name: test-binding
+ auth_method: test
+ bind_name: yolo2
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.binding.Description == 'test-binding: my description'
+ - result.operation == 'update'
+
+- name: Update a binding rule (noop)
+ community.general.consul_binding_rule:
+ name: test-binding
+ auth_method: test
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.binding.Description == 'test-binding: my description'
+ - result.operation is not defined
+
+- name: Delete a binding rule
+ community.general.consul_binding_rule:
+ name: test-binding
+ auth_method: test
+ state: absent
+ register: result
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'remove' \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_general.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_general.yml
new file mode 100644
index 000000000..2fc28efc2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_general.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: ensure unknown scheme fails
+ consul_session:
+ state: info
+ id: dummy
+ scheme: non_existent
+ token: "{{ consul_management_token }}"
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - result is failed
+
+- name: ensure SSL certificate is checked
+ consul_session:
+ state: info
+ id: dummy
+ port: 8501
+ scheme: https
+ token: "{{ consul_management_token }}"
+ 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: dummy
+ port: 8501
+ scheme: https
+ token: "{{ consul_management_token }}"
+ 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: dummy
+ port: 8501
+ scheme: https
+ token: "{{ consul_management_token }}"
+ ca_path: '{{ remote_dir }}/cert.pem'
+ register: result
+
+- assert:
+ that:
+ - result is changed
+
+- name: ensure connection errors are handled properly
+ consul_session:
+ state: info
+ id: dummy
+ token: "{{ consul_management_token }}"
+ port: 1234
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - result is failed
+ - result.msg.startswith('Could not connect to consul agent at localhost:1234, error was')
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_kv.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_kv.yml
new file mode 100644
index 000000000..6cca73137
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_kv.yml
@@ -0,0 +1,57 @@
+---
+# Copyright (c) 2024, Florian Apolloner (@apollo13)
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 key
+ consul_kv:
+ key: somekey
+ value: somevalue
+ token: "{{ consul_management_token }}"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.data.Value == 'somevalue'
+
+#- name: Test the lookup
+# assert:
+# that:
+# - lookup('community.general.consul_kv', 'somekey', token=consul_management_token) == 'somevalue'
+
+- name: Update a key with the same data
+ consul_kv:
+ key: somekey
+ value: somevalue
+ token: "{{ consul_management_token }}"
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.data.Value == 'somevalue'
+
+- name: Remove a key from the store
+ consul_kv:
+ key: somekey
+ state: absent
+ token: "{{ consul_management_token }}"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.data.Value == 'somevalue'
+
+- name: Remove a non-existant key from the store
+ consul_kv:
+ key: somekey
+ state: absent
+ token: "{{ consul_management_token }}"
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - not result.data \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_policy.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_policy.yml
new file mode 100644
index 000000000..336324f03
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_policy.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: Create a policy with rules
+ consul_policy:
+ name: foo-access
+ rules: |
+ key "foo" {
+ policy = "read"
+ }
+ key "private/foo" {
+ policy = "deny"
+ }
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.policy.Name == 'foo-access'
+ - result.operation == 'create'
+
+- name: Update the rules associated to a policy
+ consul_policy:
+ name: foo-access
+ rules: |
+ key "foo" {
+ policy = "read"
+ }
+ key "private/foo" {
+ policy = "deny"
+ }
+ event "bbq" {
+ policy = "write"
+ }
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'update'
+
+- name: Update reports not changed when updating again without changes
+ consul_policy:
+ name: foo-access
+ rules: |
+ key "foo" {
+ policy = "read"
+ }
+ key "private/foo" {
+ policy = "deny"
+ }
+ event "bbq" {
+ policy = "write"
+ }
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.operation is not defined
+
+- name: Remove a policy
+ consul_policy:
+ name: foo-access
+ state: absent
+ register: result
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'remove' \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_role.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_role.yml
new file mode 100644
index 000000000..9b0504e0b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_role.yml
@@ -0,0 +1,194 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 policy with rules
+ consul_policy:
+ name: foo-access-for-role
+ rules: |
+ key "foo" {
+ policy = "read"
+ }
+ key "private/foo" {
+ policy = "deny"
+ }
+ register: policy_result
+
+- name: Create another policy with rules
+ consul_policy:
+ name: bar-access-for-role
+ rules: |
+ key "bar" {
+ policy = "read"
+ }
+ key "private/bar" {
+ policy = "deny"
+ }
+ register: policy_result
+
+- name: Create a role with policy
+ consul_role:
+ name: foo-role-with-policy
+ policies:
+ - name: "foo-access-for-role"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.Name == 'foo-role-with-policy'
+ - result.operation == 'create'
+
+- name: Update policy description, in check mode
+ consul_role:
+ name: foo-role-with-policy
+ description: "Testing updating description"
+ check_mode: yes
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.Description == "Testing updating description"
+ - result.role.Policies.0.Name == 'foo-access-for-role'
+ - result.operation == 'update'
+
+- name: Update policy to add the description
+ consul_role:
+ name: foo-role-with-policy
+ description: "Role for testing policies"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.Description == "Role for testing policies"
+ - result.role.Policies.0.Name == 'foo-access-for-role'
+ - result.operation == 'update'
+
+- name: Update the role with another policy, also testing leaving description blank
+ consul_role:
+ name: foo-role-with-policy
+ policies:
+ - name: "foo-access-for-role"
+ - name: "bar-access-for-role"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.Policies.0.Name == 'foo-access-for-role'
+ - result.role.Policies.1.Name == 'bar-access-for-role'
+ - result.role.Description == "Role for testing policies"
+ - result.operation == 'update'
+
+- name: Create a role with service identity
+ consul_role:
+ name: role-with-service-identity
+ service_identities:
+ - name: web
+ datacenters:
+ - dc1
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities.0.ServiceName == "web"
+ - result.role.ServiceIdentities.0.Datacenters.0 == "dc1"
+
+- name: Update the role with service identity in check mode
+ consul_role:
+ name: role-with-service-identity
+ service_identities:
+ - name: web
+ datacenters:
+ - dc2
+ register: result
+ check_mode: yes
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities.0.ServiceName == "web"
+ - result.role.ServiceIdentities.0.Datacenters.0 == "dc2"
+
+- name: Update the role with service identity to add a policy, leaving the service id unchanged
+ consul_role:
+ name: role-with-service-identity
+ policies:
+ - name: "foo-access-for-role"
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities.0.ServiceName == "web"
+ - result.role.ServiceIdentities.0.Datacenters.0 == "dc1"
+ - result.role.Policies.0.Name == 'foo-access-for-role'
+
+- name: Update the role with service identity to remove the policies
+ consul_role:
+ name: role-with-service-identity
+ policies: []
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities.0.ServiceName == "web"
+ - result.role.ServiceIdentities.0.Datacenters.0 == "dc1"
+ - result.role.Policies is not defined
+
+- name: Update the role with service identity to remove the node identities, in check mode
+ consul_role:
+ name: role-with-service-identity
+ node_identities: []
+ register: result
+ check_mode: yes
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities.0.ServiceName == "web"
+ - result.role.ServiceIdentities.0.Datacenters.0 == "dc1"
+ - result.role.Policies is not defined
+ - result.role.NodeIdentities == [] # in check mode the cleared field is returned as an empty array
+
+- name: Update the role with service identity to remove the service identities
+ consul_role:
+ name: role-with-service-identity
+ service_identities: []
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.ServiceIdentities is not defined # in normal mode the dictionary is removed from the result
+ - result.role.Policies is not defined
+
+- name: Create a role with node identity
+ consul_role:
+ name: role-with-node-identity
+ node_identities:
+ - name: node-1
+ datacenter: dc2
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.role.NodeIdentities.0.NodeName == "node-1"
+ - result.role.NodeIdentities.0.Datacenter == "dc2"
+
+- name: Remove the last role
+ consul_role:
+ name: role-with-node-identity
+ state: absent
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'remove' \ No newline at end of file
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
index 543668964..7f852a36d 100644
--- 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
@@ -52,7 +52,7 @@
- name: ensure session was created
assert:
that:
- - test_session_found|default(False)
+ - test_session_found|default(false)
- name: fetch info about a session
consul_session:
@@ -75,61 +75,6 @@
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
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_token.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_token.yml
new file mode 100644
index 000000000..9b3679ef1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_token.yml
@@ -0,0 +1,88 @@
+---
+# Copyright (c) 2024, Florian Apolloner (@apollo13)
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 policy with rules
+ community.general.consul_policy:
+ name: "{{ item }}"
+ rules: |
+ key "foo" {
+ policy = "read"
+ }
+ loop:
+ - foo-access
+ - foo-access2
+
+- name: Create token without accessor
+ community.general.consul_token:
+ state: present
+ register: simple_create_result
+
+- assert:
+ that:
+ - simple_create_result is changed
+ - simple_create_result.token.AccessorID
+ - simple_create_result.operation == 'create'
+
+- name: Create token
+ community.general.consul_token:
+ state: present
+ accessor_id: 07a7de84-c9c7-448a-99cc-beaf682efd21
+ service_identities:
+ - service_name: test
+ datacenters: [test1, test2]
+ node_identities:
+ - node_name: test
+ datacenter: test
+ policies:
+ - name: foo-access
+ - name: foo-access2
+ expiration_ttl: 1h
+ register: create_result
+
+- assert:
+ that:
+ - create_result is changed
+ - create_result.token.AccessorID == "07a7de84-c9c7-448a-99cc-beaf682efd21"
+ - create_result.operation == 'create'
+
+- name: Update token
+ community.general.consul_token:
+ state: present
+ accessor_id: 07a7de84-c9c7-448a-99cc-beaf682efd21
+ description: Testing
+ policies:
+ - id: "{{ create_result.token.Policies[-1].ID }}"
+ service_identities: []
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result.operation == 'update'
+
+- name: Update token (noop)
+ community.general.consul_token:
+ state: present
+ accessor_id: 07a7de84-c9c7-448a-99cc-beaf682efd21
+ policies:
+ - id: "{{ create_result.token.Policies[-1].ID }}"
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.operation is not defined
+
+- name: Remove token
+ community.general.consul_token:
+ state: absent
+ accessor_id: 07a7de84-c9c7-448a-99cc-beaf682efd21
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - not result.token
+ - result.operation == 'remove'
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
index a2b63ac95..6fef2b998 100644
--- a/ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml
@@ -10,8 +10,8 @@
- 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_version: 1.13.2
+ consul_uri: https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_{{ ansible_system | lower }}_{{ consul_arch }}.zip
consul_cmd: '{{ remote_tmp_dir }}/consul'
block:
- name: Install requests<2.20 (CentOS/RHEL 6)
@@ -76,14 +76,32 @@
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: Bootstrap ACL
+ consul_acl_bootstrap:
+ register: consul_bootstrap_result
+ - set_fact:
+ consul_management_token: '{{ consul_bootstrap_result.result.SecretID }}'
- name: Create some data
- command: '{{ consul_cmd }} kv put data/value{{ item }} foo{{ item }}'
+ command: '{{ consul_cmd }} kv put -token={{consul_management_token}} data/value{{ item }} foo{{ item }}'
loop:
- 1
- 2
- 3
- - import_tasks: consul_session.yml
+ - import_tasks: consul_general.yml
+ - import_tasks: consul_kv.yml
+
+ - block:
+ - import_tasks: consul_session.yml
+ - import_tasks: consul_policy.yml
+ - import_tasks: consul_role.yml
+ - import_tasks: consul_token.yml
+ - import_tasks: consul_auth_method.yml
+ - import_tasks: consul_binding_rule.yml
+ module_defaults:
+ group/community.general.consul:
+ token: "{{ consul_management_token }}"
+
always:
- name: Kill consul process
shell: kill $(cat {{ remote_tmp_dir }}/consul.pid)
- ignore_errors: true
+ ignore_errors: true \ No newline at end of file
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
index 96da5d664..91bfb08ae 100644
--- 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
@@ -12,3 +12,8 @@ ports {
}
key_file = "{{ remote_dir }}/privatekey.pem"
cert_file = "{{ remote_dir }}/cert.pem"
+acl {
+ enabled = true
+ default_policy = "deny"
+ down_policy = "extend-cache"
+}
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
index 0e4651724..0d6637811 100644
--- a/ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml
@@ -10,12 +10,6 @@
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
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
index fdd8bd87b..9bd5f4150 100644
--- 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
@@ -17,25 +17,25 @@
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.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 }}'"
+ - "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}}'"
+ - "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
@@ -45,7 +45,7 @@
- "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}}'"
+ - "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
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/aliases b/ansible_collections/community/general/tests/integration/targets/django_manage/aliases
index 98aed9e9d..979054916 100644
--- a/ansible_collections/community/general/tests/integration/targets/django_manage/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/aliases
@@ -11,5 +11,10 @@ skip/rhel8.2
skip/rhel8.3
skip/rhel8.4
skip/rhel8.5
+skip/rhel8.6
+skip/rhel8.7
+skip/rhel8.8
skip/rhel9.0
skip/rhel9.1
+skip/rhel9.2
+skip/rhel9.3
diff --git a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/aliases b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/aliases
new file mode 100644
index 000000000..11c37f6bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ejabberd_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/3
+skip/osx
+skip/macos
+skip/freebsd
+skip/alpine
+skip/rhel
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/handlers/main.yml
new file mode 100644
index 000000000..16eed4733
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/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 ejabberd
+ ansible.builtin.package:
+ name: ejabberd
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ejabberd_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_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml
new file mode 100644
index 000000000..33e07b785
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml
@@ -0,0 +1,122 @@
+---
+####################################################################
+# 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: Bail out if not supported
+ ansible.builtin.meta: end_play
+ when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora')
+
+
+- name: Remove ejabberd
+ ansible.builtin.package:
+ name: ejabberd
+ state: absent
+
+- name: Create user without ejabberdctl installed
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ password: pa$$w0rd
+ state: present
+ register: user_no_ejabberdctl
+ ignore_errors: true
+
+- name: Install ejabberd
+ ansible.builtin.package:
+ name: ejabberd
+ state: present
+ notify: Remove ejabberd
+
+- name: Make runnable on Arch
+ community.general.ini_file:
+ path: /usr/lib/systemd/system/ejabberd.service
+ section: Service
+ option: "{{ item }}"
+ state: absent
+ loop:
+ - PrivateDevices
+ - AmbientCapabilities
+ when: ansible_distribution == 'Archlinux'
+
+- name: Make installable on Arch
+ systemd:
+ daemon_reload: true
+ when: ansible_distribution == 'Archlinux'
+
+- ansible.builtin.service:
+ name: ejabberd
+ state: started
+
+- name: Create user alice (check)
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ password: pa$$w0rd
+ state: present
+ check_mode: true
+ register: user_alice_check
+
+- name: Create user alice
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ password: pa$$w0rd
+ state: present
+ register: user_alice
+
+- name: Create user alice (idempotency)
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ password: pa$$w0rd
+ state: present
+ register: user_alice_idempot
+
+- name: Create user alice (change password)
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ password: different_pa$$w0rd
+ state: present
+ register: user_alice_chgpw
+
+- name: Remove user alice (check)
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ state: absent
+ register: remove_alice_check
+ check_mode: true
+
+- name: Remove user alice
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ state: absent
+ register: remove_alice
+
+- name: Remove user alice (idempotency)
+ community.general.ejabberd_user:
+ host: localhost
+ username: alice
+ state: absent
+ register: remove_alice_idempot
+
+- name: Assertions
+ ansible.builtin.assert:
+ that:
+ - user_no_ejabberdctl is failed
+ - "'Failed to find required executable' in user_no_ejabberdctl.msg"
+ - user_alice_check is changed
+ - user_alice is changed
+ - user_alice_idempot is not changed
+ - user_alice_chgpw is changed
+ - remove_alice_check is changed
+ - remove_alice is changed
+ - remove_alice_idempot is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/etcd3/aliases b/ansible_collections/community/general/tests/integration/targets/etcd3/aliases
index 264446580..78b1fff07 100644
--- a/ansible_collections/community/general/tests/integration/targets/etcd3/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/etcd3/aliases
@@ -8,5 +8,4 @@ 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/filesize/tasks/sparse.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml
index 79145b6e2..348a1eea1 100644
--- a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml
@@ -5,10 +5,10 @@
# Test module with sparse files
-- name: Create a huge sparse file of 4TB (check mode)
+- name: Create a huge sparse file of 2TB (check mode)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4TB
+ size: 2TB
sparse: true
register: filesize_test_sparse_01
check_mode: true
@@ -20,10 +20,10 @@
register: filesize_stat_sparse_01
-- name: Create a huge sparse file of 4TB
+- name: Create a huge sparse file of 2TB
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4TB
+ size: 2TB
sparse: true
register: filesize_test_sparse_02
@@ -34,34 +34,34 @@
register: filesize_stat_sparse_02
-- name: Create a huge sparse file of 4TB (4000GB) (check mode, idempotency)
+- name: Create a huge sparse file of 2TB (2000GB) (check mode, idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4000GB
+ size: 2000GB
sparse: true
register: filesize_test_sparse_03
check_mode: true
-- name: Create a huge sparse file of 4TB (4000GB) (idempotency)
+- name: Create a huge sparse file of 2TB (2000GB) (idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4000GB
+ size: 2000GB
sparse: true
register: filesize_test_sparse_04
-- name: Create a huge sparse file of 4TB (4000000 × 1MB) (check mode, idempotency)
+- name: Create a huge sparse file of 2TB (2000000 × 1MB) (check mode, idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4000000
+ size: 2000000
blocksize: 1MB
sparse: true
register: filesize_test_sparse_05
check_mode: true
-- name: Create a huge sparse file of 4TB (4000000 × 1MB) (idempotency)
+- name: Create a huge sparse file of 2TB (2000000 × 1MB) (idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4000000
+ size: 2000000
blocksize: 1MB
sparse: true
register: filesize_test_sparse_06
@@ -89,15 +89,15 @@
- 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.filesize.bytes == 2*1000**4
+ - filesize_test_sparse_02.filesize.bytes == 2*1000**4
+ - filesize_test_sparse_03.filesize.bytes == 2*1000**4
+ - filesize_test_sparse_04.filesize.bytes == 2*1000**4
+ - filesize_test_sparse_05.filesize.bytes == 2*1000**4
+ - filesize_test_sparse_06.filesize.bytes == 2*1000**4
- - filesize_test_sparse_01.size_diff == 4*1000**4
- - filesize_test_sparse_02.size_diff == 4*1000**4
+ - filesize_test_sparse_01.size_diff == 2*1000**4
+ - filesize_test_sparse_02.size_diff == 2*1000**4
- filesize_test_sparse_03.size_diff == 0
- filesize_test_sparse_04.size_diff == 0
- filesize_test_sparse_05.size_diff == 0
@@ -106,24 +106,24 @@
- 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
+ - filesize_test_sparse_02.size == 2*1000**4
+ - filesize_test_sparse_03.size == 2*1000**4
+ - filesize_test_sparse_04.size == 2*1000**4
+ - filesize_test_sparse_05.size == 2*1000**4
+ - filesize_test_sparse_06.size == 2*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
+ - filesize_stat_sparse_02.stat.size == 2*1000**4
+ - filesize_stat_sparse_06.stat.size == 2*1000**4
-- name: Change sparse file size to 4TiB (check mode)
+- name: Change sparse file size to 2TiB (check mode)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4TiB
+ size: 2TiB
sparse: true
register: filesize_test_sparse_11
check_mode: true
@@ -135,10 +135,10 @@
register: filesize_stat_sparse_11
-- name: Change sparse file size to 4TiB
+- name: Change sparse file size to 2TiB
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4TiB
+ size: 2TiB
sparse: true
register: filesize_test_sparse_12
@@ -149,18 +149,18 @@
register: filesize_stat_sparse_12
-- name: Change sparse file size to 4TiB (4096GiB) (check mode, idempotency)
+- name: Change sparse file size to 2TiB (2048GiB) (check mode, idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4096GiB
+ size: 2048GiB
sparse: true
register: filesize_test_sparse_13
check_mode: true
-- name: Change sparse file size to 4TiB (4096GiB) (idempotency)
+- name: Change sparse file size to 2TiB (2048GiB) (idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4096GiB
+ size: 2048GiB
sparse: true
register: filesize_test_sparse_14
@@ -183,26 +183,26 @@
- 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_11.size_diff == 199023255552
+ - filesize_test_sparse_12.size_diff == 199023255552
- 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_test_sparse_11.size == 2000000000000
+ - filesize_test_sparse_12.size == 2199023255552
+ - filesize_test_sparse_13.size == 2199023255552
+ - filesize_test_sparse_14.size == 2199023255552
- - filesize_stat_sparse_11.stat.size == 4000000000000
- - filesize_stat_sparse_12.stat.size == 4398046511104
- - filesize_stat_sparse_14.stat.size == 4398046511104
+ - filesize_stat_sparse_11.stat.size == 2000000000000
+ - filesize_stat_sparse_12.stat.size == 2199023255552
+ - filesize_stat_sparse_14.stat.size == 2199023255552
-- name: Change sparse file size to 4.321TB (check mode)
+- name: Change sparse file size to 2.321TB (check mode)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4.321TB
+ size: 2.321TB
sparse: true
register: filesize_test_sparse_21
check_mode: true
@@ -214,10 +214,10 @@
register: filesize_stat_sparse_21
-- name: Change sparse file size to 4.321TB
+- name: Change sparse file size to 2.321TB
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4.321TB
+ size: 2.321TB
sparse: true
register: filesize_test_sparse_22
@@ -228,19 +228,19 @@
register: filesize_stat_sparse_22
-- name: Change sparse file size to 4321×1GB (check mode, idempotency)
+- name: Change sparse file size to 2321×1GB (check mode, idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4321
+ size: 2321
blocksize: 1GB
sparse: true
register: filesize_test_sparse_23
check_mode: true
-- name: Change sparse file size to 4321×1GB (idempotency)
+- name: Change sparse file size to 2321×1GB (idempotency)
community.general.filesize:
path: "{{ filesize_testfile }}"
- size: 4321
+ size: 2321
blocksize: 1GB
sparse: true
register: filesize_test_sparse_24
@@ -264,19 +264,19 @@
- 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_21.size_diff == 2321*1000**3 - 2*1024**4
+ - filesize_test_sparse_22.size_diff == 2321*1000**3 - 2*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_test_sparse_21.size == 2199023255552
+ - filesize_test_sparse_22.size == 2321000000000
+ - filesize_test_sparse_23.size == 2321000000000
+ - filesize_test_sparse_24.size == 2321000000000
- - filesize_stat_sparse_21.stat.size == 4398046511104
- - filesize_stat_sparse_22.stat.size == 4321000000000
- - filesize_stat_sparse_24.stat.size == 4321000000000
+ - filesize_stat_sparse_21.stat.size == 2199023255552
+ - filesize_stat_sparse_22.stat.size == 2321000000000
+ - filesize_stat_sparse_24.stat.size == 2321000000000
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
index 0448d8602..ec446d241 100644
--- a/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml
@@ -11,23 +11,23 @@ tested_filesystems:
# - 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.2.0 requires at least 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}
+ ext4: {fssize: 10, grow: true, new_uuid: 'random'}
+ ext4dev: {fssize: 10, grow: true, new_uuid: 'random'}
+ ext3: {fssize: 10, grow: true, new_uuid: 'random'}
+ ext2: {fssize: 10, grow: true, new_uuid: 'random'}
+ xfs: {fssize: 300, grow: false, new_uuid: 'generate'} # grow requires a mounted filesystem
+ btrfs: {fssize: 150, grow: false, new_uuid: null} # grow requires a mounted filesystem
+ reiserfs: {fssize: 33, grow: false, new_uuid: null} # grow not implemented
+ vfat: {fssize: 20, grow: true, new_uuid: null}
+ ocfs2: {fssize: '{{ ocfs2_fssize }}', grow: false, new_uuid: null} # grow not implemented
+ f2fs: {fssize: '{{ f2fs_fssize|default(60) }}', grow: 'f2fs_version is version("1.10.0", ">=")', new_uuid: null}
+ lvm: {fssize: 20, grow: true, new_uuid: 'something'}
+ swap: {fssize: 10, grow: false, new_uuid: null} # grow not implemented
+ ufs: {fssize: 10, grow: true, new_uuid: null}
get_uuid_any: "blkid -c /dev/null -o value -s UUID {{ dev }}"
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
index 0ff0f2309..0c15c2155 100644
--- a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml
@@ -29,6 +29,7 @@
fstype: '{{ item.0.key }}'
fssize: '{{ item.0.value.fssize }}'
grow: '{{ item.0.value.grow }}'
+ new_uuid: '{{ item.0.value.new_uuid }}'
action: '{{ item.1 }}'
when:
# FreeBSD limited support
@@ -83,7 +84,7 @@
# 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 }}"
+ loop: "{{ query('dict', tested_filesystems)|product(['create_fs', 'reset_fs_uuid', 'overwrite_another_fs', 'remove_fs', 'set_fs_uuid_on_creation', 'set_fs_uuid_on_creation_with_opts'])|list }}"
# With FreeBSD extended support (util-linux is not available before 12.2)
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/reset_fs_uuid.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/reset_fs_uuid.yml
new file mode 100644
index 000000000..77dad2203
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/reset_fs_uuid.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
+
+# Skip UUID reset tests for FreeBSD due to "xfs_admin: only 'rewrite' supported on V5 fs"
+- when:
+ - new_uuid | default(False)
+ - not (ansible_system == "FreeBSD" and fstype == "xfs")
+ block:
+ - name: "Create filesystem ({{ fstype }})"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ register: fs_result
+
+ - name: "Get UUID of created filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid
+
+ - name: "Reset filesystem ({{ fstype }}) UUID"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ uuid: "{{ new_uuid }}"
+ register: fs_resetuuid_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 changed"
+ ansible.builtin.assert:
+ that:
+ - 'fs_resetuuid_result is changed'
+ - 'fs_resetuuid_result is success'
+ - 'uuid.stdout != uuid2.stdout'
+
+ - 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: "Reset filesystem ({{ fstype }}) UUID and resizefs"
+ ignore_errors: true
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ uuid: "{{ new_uuid }}"
+ resizefs: true
+ register: fs_resetuuid_and_resizefs_result
+
+ - name: "Assert that filesystem UUID reset and resizefs failed"
+ ansible.builtin.assert:
+ that: fs_resetuuid_and_resizefs_result is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation.yml
new file mode 100644
index 000000000..f52c44d65
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation.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: "Generate a random UUID"
+ ansible.builtin.set_fact:
+ random_uuid: '{{ "first_random_uuid" | ansible.builtin.to_uuid }}'
+
+# Skip UUID set at creation tests for FreeBSD due to "xfs_admin: only 'rewrite' supported on V5 fs"
+- when:
+ - new_uuid | default(False)
+ - not (ansible_system == "FreeBSD" and fstype == "xfs")
+ block:
+ - name: "Create filesystem ({{ fstype }}) with UUID"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ uuid: '{{ random_uuid }}'
+ register: fs_result
+
+ - name: "Get UUID of the created filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid
+
+ - name: "Assert that filesystem UUID is the random UUID set on creation"
+ ansible.builtin.assert:
+ that: (random_uuid | replace('-','')) == ( uuid.stdout | replace('-',''))
+
+- when: not (new_uuid | default(False))
+ block:
+ - name: "Create filesystem ({{ fstype }}) without UUID support"
+ ignore_errors: true
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ uuid: '{{ random_uuid }}'
+ register: fs_result
+
+ - name: "Assert that filesystem creation failed"
+ ansible.builtin.assert:
+ that: fs_result is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation_with_opts.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation_with_opts.yml
new file mode 100644
index 000000000..fc73e57ee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation_with_opts.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
+
+# UUID set at creation with opts for XFS is not supported
+- when:
+ - new_uuid | default(False)
+ - fstype != "xfs"
+ block:
+
+ - name: "Generate random UUIDs"
+ ansible.builtin.set_fact:
+ random_uuid: '{{ "first_random_uuid" | ansible.builtin.to_uuid }}'
+ random_uuid2: '{{ "second_random_uuid" | ansible.builtin.to_uuid }}'
+
+ - name: "Create filesystem ({{ fstype }}) with fix UUID as opt"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ opts: "{{ ((fstype == 'lvm') | ansible.builtin.ternary('--norestorefile --uuid ', '-U ')) + random_uuid2 }}"
+ uuid: '{{ random_uuid }}'
+ register: fs_result2
+
+ - name: "Get UUID of the created filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid2
+
+ - name: "Assert that filesystem UUID is the one set on creation with opt"
+ ansible.builtin.assert:
+ that: (random_uuid2 | replace('-','')) == ( uuid2.stdout | replace('-',''))
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases b/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases
@@ -3,4 +3,3 @@
# 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/aliases b/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases
index e8051e042..343f119da 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases
@@ -3,4 +3,3 @@
# 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_kv/aliases b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases
@@ -3,4 +3,3 @@
# 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/aliases b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases
@@ -3,4 +3,3 @@
# 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_ini/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml
new file mode 100644
index 000000000..a2eca36a6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml
@@ -0,0 +1,60 @@
+---
+# Copyright (c) 2023, Steffen Scheib <steffen@scheib.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: 'Define ini_test_dict'
+ ansible.builtin.set_fact:
+ ini_test_dict:
+ section_name:
+ key_name: 'key value'
+
+ another_section:
+ connection: 'ssh'
+
+- name: 'Write INI file that reflects ini_test_dict to {{ ini_test_file }}'
+ ansible.builtin.copy:
+ dest: '{{ ini_test_file }}'
+ content: |
+ [section_name]
+ key_name=key value
+
+ [another_section]
+ connection=ssh
+
+- name: 'Slurp the test file: {{ ini_test_file }}'
+ ansible.builtin.slurp:
+ src: '{{ ini_test_file }}'
+ register: 'ini_file_content'
+
+- name: >-
+ Ensure defined ini_test_dict is the same when retrieved
+ from {{ ini_test_file }}
+ ansible.builtin.assert:
+ that:
+ - 'ini_file_content.content | b64decode | community.general.from_ini ==
+ ini_test_dict'
+
+- name: 'Create a file that is not INI formatted: {{ ini_bad_file }}'
+ ansible.builtin.copy:
+ dest: '{{ ini_bad_file }}'
+ content: |
+ Testing a not INI formatted file.
+
+- name: 'Slurp the file that is not INI formatted: {{ ini_bad_file }}'
+ ansible.builtin.slurp:
+ src: '{{ ini_bad_file }}'
+ register: 'ini_bad_file_content'
+
+- name: 'Try parsing the bad file with from_ini: {{ ini_bad_file }}'
+ ansible.builtin.debug:
+ var: ini_bad_file_content | b64decode | community.general.from_ini
+ register: 'ini_bad_file_debug'
+ ignore_errors: true
+
+- name: 'Ensure from_ini raised the correct exception'
+ ansible.builtin.assert:
+ that:
+ - "'from_ini failed to parse given string' in ini_bad_file_debug.msg"
+ - "'File contains no section headers' in ini_bad_file_debug.msg"
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_from_ini/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/vars/main.yml
new file mode 100644
index 000000000..8c4d79327
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_ini/vars/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) 2023, Steffen Scheib <steffen@scheib.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
+
+ini_test_file: '/tmp/test.ini'
+ini_bad_file: '/tmp/bad.file'
+...
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
index e8051e042..343f119da 100644
--- 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
@@ -3,4 +3,3 @@
# 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_hashids/aliases b/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases
@@ -3,4 +3,3 @@
# 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_jc/aliases b/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases
index 0e799090e..4e1151566 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases
@@ -3,5 +3,6 @@
# 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
+skip/freebsd13.3 # FIXME - ruyaml compilation fails
+skip/freebsd14.0 # FIXME - ruyaml compilation fails
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
index cee9abd2c..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases
@@ -3,5 +3,4 @@
# 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_lists/aliases b/ansible_collections/community/general/tests/integration/targets/filter_lists/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists/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/filter_lists/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists/tasks/main.yml
new file mode 100644
index 000000000..a146e1293
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists/tasks/main.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: Test predictive list union
+ ansible.builtin.assert:
+ that:
+ - 'list1 | community.general.lists_union(list2, list3) == [1, 2, 5, 3, 4, 10, 11, 99, 101]'
+ - '[list1, list2, list3] | community.general.lists_union(flatten=True) == [1, 2, 5, 3, 4, 10, 11, 99, 101]'
+ - '[1, 2, 3] | community.general.lists_union([4, 5, 6]) == [1, 2, 3, 4, 5, 6]'
+ - '[1, 2, 3] | community.general.lists_union([3, 4, 5, 6]) == [1, 2, 3, 4, 5, 6]'
+ - '[1, 2, 3] | community.general.lists_union([3, 2, 1]) == [1, 2, 3]'
+ - '["a", "A", "b"] | community.general.lists_union(["B", "c", "C"]) == ["a", "A", "b", "B", "c", "C"]'
+ - '["a", "A", "b"] | community.general.lists_union(["b", "B", "c", "C"]) == ["a", "A", "b", "B", "c", "C"]'
+ - '["a", "A", "b"] | community.general.lists_union(["b", "A", "a"]) == ["a", "A", "b"]'
+ - '[["a"]] | community.general.lists_union([["b"], ["a"]]) == [["a"], ["b"]]'
+ - '[["a"]] | community.general.lists_union([["b"]], ["a"]) == [["a"], ["b"], "a"]'
+ - '[["a"]] | community.general.lists_union(["b"], ["a"]) == [["a"], "b", "a"]'
+
+- name: Test predictive list intersection
+ ansible.builtin.assert:
+ that:
+ - 'list1 | community.general.lists_intersect(list2, list3) == [1, 2, 5, 4]'
+ - '[list1, list2, list3] | community.general.lists_intersect(flatten=True) == [1, 2, 5, 4]'
+ - '[1, 2, 3] | community.general.lists_intersect([4, 5, 6]) == []'
+ - '[1, 2, 3] | community.general.lists_intersect([3, 4, 5, 6]) == [3]'
+ - '[1, 2, 3] | community.general.lists_intersect([3, 2, 1]) == [1, 2, 3]'
+ - '["a", "A", "b"] | community.general.lists_intersect(["B", "c", "C"]) == []'
+ - '["a", "A", "b"] | community.general.lists_intersect(["b", "B", "c", "C"]) == ["b"]'
+ - '["a", "A", "b"] | community.general.lists_intersect(["b", "A", "a"]) == ["a", "A", "b"]'
+ - '[["a"]] | community.general.lists_intersect([["b"], ["a"]]) == [["a"]]'
+ - '[["a"]] | community.general.lists_intersect([["b"]], ["a"]) == []'
+ - '[["a"]] | community.general.lists_intersect(["b"], ["a"]) == []'
+
+- name: Test predictive list difference
+ ansible.builtin.assert:
+ that:
+ - 'list1 | community.general.lists_difference(list2, list3) == []'
+ - '[list1, list2, list3] | community.general.lists_difference(flatten=True) == []'
+ - '[1, 2, 3] | community.general.lists_difference([4, 5, 6]) == [1, 2, 3]'
+ - '[1, 2, 3] | community.general.lists_difference([3, 4, 5, 6]) == [1, 2]'
+ - '[1, 2, 3] | community.general.lists_difference([3, 2, 1]) == []'
+ - '["a", "A", "b"] | community.general.lists_difference(["B", "c", "C"]) == ["a", "A", "b"]'
+ - '["a", "A", "b"] | community.general.lists_difference(["b", "B", "c", "C"]) == ["a", "A"]'
+ - '["a", "A", "b"] | community.general.lists_difference(["b", "A", "a"]) == []'
+ - '[["a"]] | community.general.lists_difference([["b"], ["a"]]) == []'
+ - '[["a"]] | community.general.lists_difference([["b"]], ["a"]) == [["a"]]'
+ - '[["a"]] | community.general.lists_difference(["b"], ["a"]) == [["a"]]'
+
+- name: Test predictive list symmetric difference
+ ansible.builtin.assert:
+ that:
+ - 'list1 | community.general.lists_symmetric_difference(list2, list3) == [11, 1, 2, 4, 5, 101]'
+ - '[list1, list2, list3] | community.general.lists_symmetric_difference(flatten=True) == [11, 1, 2, 4, 5, 101]'
+ - '[1, 2, 3] | community.general.lists_symmetric_difference([4, 5, 6]) == [1, 2, 3, 4, 5, 6]'
+ - '[1, 2, 3] | community.general.lists_symmetric_difference([3, 4, 5, 6]) == [1, 2, 4, 5, 6]'
+ - '[1, 2, 3] | community.general.lists_symmetric_difference([3, 2, 1]) == []'
+ - '["a", "A", "b"] | community.general.lists_symmetric_difference(["B", "c", "C"]) == ["a", "A", "b", "B", "c", "C"]'
+ - '["a", "A", "b"] | community.general.lists_symmetric_difference(["b", "B", "c", "C"]) == ["a", "A", "B", "c", "C"]'
+ - '["a", "A", "b"] | community.general.lists_symmetric_difference(["b", "A", "a"]) == []'
+ - '[["a"]] | community.general.lists_symmetric_difference([["b"], ["a"]]) == [["b"]]'
+ - '[["a"]] | community.general.lists_symmetric_difference([["b"]], ["a"]) == [["a"], ["b"], "a"]'
+ - '[["a"]] | community.general.lists_symmetric_difference(["b"], ["a"]) == [["a"], "b", "a"]'
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists/vars/main.yml
new file mode 100644
index 000000000..a67af1dad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists/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
+
+list1: [1, 2, 5, 3, 4, 10]
+list2: [1, 2, 3, 4, 5, 11, 99]
+list3: [1, 2, 4, 5, 10, 99, 101]
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
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases
@@ -3,4 +3,3 @@
# 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_path_join_shim/aliases b/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases
index 51baa3d7a..afda346c4 100644
--- 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
@@ -3,4 +3,3 @@
# 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_random_mac/aliases b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases
index cee9abd2c..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases
@@ -3,5 +3,4 @@
# 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_time/aliases b/ansible_collections/community/general/tests/integration/targets/filter_time/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_time/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_time/aliases
@@ -3,4 +3,3 @@
# 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_to_ini/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml
new file mode 100644
index 000000000..877d4471d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml
@@ -0,0 +1,58 @@
+---
+# Copyright (c) 2023, Steffen Scheib <steffen@scheib.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: >-
+ Write INI file that reflects using to_ini to {{ ini_test_file_filter }}
+ ansible.builtin.copy:
+ dest: '{{ ini_test_file_filter }}'
+ content: '{{ ini_test_dict | community.general.to_ini }}'
+ vars:
+ ini_test_dict:
+ section_name:
+ key_name: 'key value'
+
+ another_section:
+ connection: 'ssh'
+
+- name: 'Write INI file manually to {{ ini_test_file }}'
+ ansible.builtin.copy:
+ dest: '{{ ini_test_file }}'
+ content: |
+ [section_name]
+ key_name = key value
+
+ [another_section]
+ connection = ssh
+
+- name: 'Slurp the manually created test file: {{ ini_test_file }}'
+ ansible.builtin.slurp:
+ src: '{{ ini_test_file }}'
+ register: 'ini_file_content'
+
+- name: 'Slurp the test file created with to_ini: {{ ini_test_file_filter }}'
+ ansible.builtin.slurp:
+ src: '{{ ini_test_file_filter }}'
+ register: 'ini_file_filter_content'
+
+- name: >-
+ Ensure the manually created test file and the test file created with
+ to_ini are identical
+ ansible.builtin.assert:
+ that:
+ - 'ini_file_content.content | b64decode ==
+ ini_file_filter_content.content | b64decode'
+
+- name: 'Try to convert an empty dictionary with to_ini'
+ ansible.builtin.debug:
+ msg: '{{ {} | community.general.to_ini }}'
+ register: 'ini_empty_dict'
+ ignore_errors: true
+
+- name: 'Ensure the correct exception was raised'
+ ansible.builtin.assert:
+ that:
+ - "'to_ini received an empty dict. An empty dict cannot be converted.' in
+ ini_empty_dict.msg"
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_to_ini/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/vars/main.yml
new file mode 100644
index 000000000..9c950726b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_to_ini/vars/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) 2023, Steffen Scheib <steffen@scheib.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
+
+ini_test_file: '/tmp/test.ini'
+ini_test_file_filter: '/tmp/test_filter.ini'
+...
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
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases
@@ -3,4 +3,3 @@
# 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/aliases b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases
index bc9b4bc99..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases
@@ -3,4 +3,3 @@
# 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/gem/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml
index 362c126bf..2d615304f 100644
--- a/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml
@@ -109,7 +109,7 @@
- current_gems.stdout is not search('gist\s+\([0-9.]+\)')
when: ansible_user_uid == 0
- # Check cutom gem directory
+ # Check custom gem directory
- name: Install gem in a custom directory with incorrect options
gem:
name: gist
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
index 92eeb7eb9..29d3e8a0e 100644
--- a/ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig
@@ -4,3 +4,8 @@
[http]
proxy = foo
+
+[push]
+pushoption = merge_request.create
+pushoption = merge_request.draft
+pushoption = merge_request.target=foobar
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
index a61ffcc68..c410bfe18 100644
--- 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
@@ -30,3 +30,4 @@
- set_result.diff.after == option_value + "\n"
- get_result is not changed
- get_result.config_value == option_value
+... \ No newline at end of file
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
index 4dc72824c..5fddaf764 100644
--- 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
@@ -13,6 +13,7 @@
import_tasks: setup.yml
- block:
+ - import_tasks: set_value.yml
# testing parameters exclusion: state and list_all
- import_tasks: exclusion_state_list-all.yml
# testing get/set option without state
@@ -31,5 +32,7 @@
- import_tasks: unset_check_mode.yml
# testing for case in issue #1776
- import_tasks: set_value_with_tilde.yml
+ - import_tasks: set_multi_value.yml
+ - import_tasks: unset_multi_value.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/set_multi_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_multi_value.yml
new file mode 100644
index 000000000..8d2710b76
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_multi_value.yml
@@ -0,0 +1,79 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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: push.pushoption
+ add_mode: add
+ value: "{{ item }}"
+ state: present
+ scope: global
+ loop:
+ - 'merge_request.create'
+ - 'merge_request.draft'
+ - 'merge_request.target=foobar'
+ register: set_result1
+
+- name: setting value
+ git_config:
+ name: push.pushoption
+ add_mode: add
+ value: "{{ item }}"
+ state: present
+ scope: global
+ loop:
+ - 'merge_request.create'
+ - 'merge_request.draft'
+ - 'merge_request.target=foobar'
+ register: set_result2
+
+- name: getting the multi-value
+ git_config:
+ name: push.pushoption
+ scope: global
+ register: get_single_result
+
+- name: getting all values for the single option
+ git_config_info:
+ name: push.pushoption
+ scope: global
+ register: get_all_result
+
+- name: replace-all values
+ git_config:
+ name: push.pushoption
+ add_mode: replace-all
+ value: merge_request.create
+ state: present
+ scope: global
+ register: set_result3
+
+- name: assert set changed and value is correct
+ assert:
+ that:
+ - set_result1.results[0] is changed
+ - set_result1.results[1] is changed
+ - set_result1.results[2] is changed
+ - set_result2.results[0] is not changed
+ - set_result2.results[1] is not changed
+ - set_result2.results[2] is not changed
+ - set_result3 is changed
+ - get_single_result.config_value == 'merge_request.create'
+ - 'get_all_result.config_values == {"push.pushoption": ["merge_request.create", "merge_request.draft", "merge_request.target=foobar"]}'
+
+- name: assert the diffs are also right
+ assert:
+ that:
+ - set_result1.results[0].diff.before == "\n"
+ - set_result1.results[0].diff.after == "merge_request.create\n"
+ - set_result1.results[1].diff.before == "merge_request.create\n"
+ - set_result1.results[1].diff.after == ["merge_request.create", "merge_request.draft"]
+ - set_result1.results[2].diff.before == ["merge_request.create", "merge_request.draft"]
+ - set_result1.results[2].diff.after == ["merge_request.create", "merge_request.draft", "merge_request.target=foobar"]
+ - set_result3.diff.before == ["merge_request.create", "merge_request.draft", "merge_request.target=foobar"]
+ - set_result3.diff.after == "merge_request.create\n"
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value.yml
new file mode 100644
index 000000000..774e3136a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value.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
+
+- import_tasks: setup_no_value.yml
+
+- name: setting value
+ git_config:
+ name: core.name
+ value: foo
+ scope: global
+ register: set_result1
+
+- name: setting another value for same name
+ git_config:
+ name: core.name
+ value: bar
+ scope: global
+ register: set_result2
+
+- name: getting value
+ git_config:
+ name: core.name
+ scope: global
+ register: get_result
+
+- name: assert set changed and value is correct
+ assert:
+ that:
+ - set_result1 is changed
+ - set_result2 is changed
+ - get_result is not changed
+ - get_result.config_value == 'bar'
+ - set_result1.diff.before == "\n"
+ - set_result1.diff.after == "foo\n"
+ - set_result2.diff.before == "foo\n"
+ - set_result2.diff.after == "bar\n"
+...
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
index f78e709bd..3ca9023aa 100644
--- 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
@@ -11,7 +11,7 @@
value: '~/foo/bar'
state: present
scope: global
- register: set_result
+ register: set_result1
- name: setting value again
git_config:
@@ -30,7 +30,7 @@
- name: assert set changed and value is correct
assert:
that:
- - set_result is changed
+ - set_result1 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/unset_multi_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_multi_value.yml
new file mode 100644
index 000000000..4cb9dee49
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_multi_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 "push.pushoption"
+ git_config:
+ name: push.pushoption
+ scope: global
+ state: absent
+ register: unset_result
+
+- name: getting all pushoptions values
+ git_config_info:
+ name: push.pushoption
+ scope: global
+ register: get_all_result
+
+- name: assert unsetting muti-values
+ assert:
+ that:
+ - unset_result is changed
+ - 'get_all_result.config_values == {"push.pushoption": []}'
+ - unset_result.diff.before == ["merge_request.create", "merge_request.draft", "merge_request.target=foobar"]
+ - unset_result.diff.after == "\n"
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/aliases b/ansible_collections/community/general/tests/integration/targets/git_config_info/aliases
new file mode 100644
index 000000000..7b8c653de
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/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_info/files/gitconfig b/ansible_collections/community/general/tests/integration/targets/git_config_info/files/gitconfig
new file mode 100644
index 000000000..d0590b3f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/files/gitconfig
@@ -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
+
+[credential "https://some.com"]
+ username = yolo
+[user]
+ name = foobar
+[push]
+ pushoption = merge_request.create
+ pushoption = merge_request.draft
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_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_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/error_handling.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/error_handling.yml
new file mode 100644
index 000000000..1b84fee50
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/error_handling.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
+
+- import_tasks: "setup_file.yml"
+
+- name: getting all system configs
+ git_config_info:
+ scope: system
+ register: get_result1
+
+- name: getting all system configs for a key
+ git_config_info:
+ name: user.name
+ scope: system
+ register: get_result2
+
+- name: assert value is correct
+ assert:
+ that:
+ - get_result1.config_value == ""
+ - 'get_result1.config_values == {}'
+ - get_result2.config_value == ""
+ - 'get_result2.config_values == {"user.name": []}'
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_all_values.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_all_values.yml
new file mode 100644
index 000000000..301051a42
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_all_values.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_tasks: "{{ item.import_file }}"
+
+- name: getting all values (as list) for a file config
+ git_config_info:
+ scope: "{{ item.git_scope }}"
+ path: "{{ item.git_file | default(omit) }}"
+ register: get_result
+
+- name: assert value is correct
+ assert:
+ that:
+ - get_result.config_value == ""
+ - 'get_result.config_values == {"credential.https://some.com.username": ["yolo"], "user.name": ["foobar"], "push.pushoption": ["merge_request.create", "merge_request.draft"]}'
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_multi_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_multi_value.yml
new file mode 100644
index 000000000..14fa2800c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_multi_value.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
+
+- include_tasks: "{{ item.import_file }}"
+
+- name: getting only a single value (as string) from an option with multiple values in the git config file
+ git_config_info:
+ name: push.pushoption
+ scope: "{{ item.git_scope }}"
+ path: "{{ item.git_file | default(omit) }}"
+ register: get_result
+
+- name: assert value is correct
+ assert:
+ that:
+ - get_result.config_value == "merge_request.create"
+ - 'get_result.config_values == {"push.pushoption": ["merge_request.create", "merge_request.draft"]}'
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_simple_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_simple_value.yml
new file mode 100644
index 000000000..83cd19a0b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_simple_value.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
+
+- include_tasks: "{{ item.import_file }}"
+
+- name: getting simple file value1
+ git_config_info:
+ name: user.name
+ scope: "{{ item.git_scope }}"
+ path: "{{ item.git_file | default(omit) }}"
+ register: get_result1
+
+- name: getting simple file value2
+ git_config_info:
+ name: "credential.https://some.com.username"
+ scope: "{{ item.git_scope }}"
+ path: "{{ item.git_file | default(omit) }}"
+ register: get_result2
+
+- name: getting not existing value
+ git_config_info:
+ name: "user.email"
+ scope: "{{ item.git_scope }}"
+ path: "{{ item.git_file | default(omit) }}"
+ register: get_result3
+
+- name: assert value is correct
+ assert:
+ that:
+ - get_result1.config_value == "foobar"
+ - 'get_result1.config_values == {"user.name": ["foobar"]}'
+ - get_result2.config_value == "yolo"
+ - 'get_result2.config_values == {"credential.https://some.com.username": ["yolo"]}'
+ - get_result3.config_value == ""
+ - 'get_result3.config_values == {"user.email": []}'
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/main.yml
new file mode 100644
index 000000000..993238805
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/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 git_config_info 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:
+ - include_tasks: get_simple_value.yml
+ loop:
+ - { import_file: setup_global.yml, git_scope: 'global' }
+ - { import_file: setup_file.yml, git_scope: 'file', git_file: "{{ remote_tmp_dir }}/gitconfig_file" }
+
+ - include_tasks: get_multi_value.yml
+ loop:
+ - { import_file: setup_global.yml, git_scope: 'global' }
+ - { import_file: setup_file.yml, git_scope: 'file', git_file: "{{ remote_tmp_dir }}/gitconfig_file" }
+
+ - include_tasks: get_all_values.yml
+ loop:
+ - { import_file: setup_global.yml, git_scope: 'global' }
+ - { import_file: setup_file.yml, git_scope: 'file', git_file: "{{ remote_tmp_dir }}/gitconfig_file" }
+
+ - include_tasks: error_handling.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_info/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup.yml
new file mode 100644
index 000000000..6e5516da5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/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_info/tasks/setup_file.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_file.yml
new file mode 100644
index 000000000..854b10997
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_file.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: delete global config
+ file:
+ path: ~/.gitconfig
+ state: absent
+
+- name: set up file config
+ copy:
+ src: gitconfig
+ dest: "{{ remote_tmp_dir }}/gitconfig_file"
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_global.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_global.yml
new file mode 100644
index 000000000..a9e045a57
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_global.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: delete file config
+ file:
+ path: "{{ remote_tmp_dir }}/gitconfig_file"
+ state: absent
+
+- name: setup global config
+ copy:
+ src: gitconfig
+ dest: ~/.gitconfig
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config_info/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config_info/vars/main.yml
new file mode 100644
index 000000000..55c3d1738
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config_info/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
+
+git_version_supporting_includes: 1.7.10
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/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_access_token/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/defaults/main.yml
new file mode 100644
index 000000000..1b0dab289
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/defaults/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 #
+####################################################################
+
+# Copyright (c) 2024, Zoran Krleza <zoran.krleza@true-north.hr>
+# GNU General Public License v3.0+ (see LICENSES/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:
+gitlab_api_url:
+gitlab_validate_certs: false
+gitlab_group_name:
+gitlab_token_name:
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/tasks/main.yml
new file mode 100644
index 000000000..4e6234238
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/tasks/main.yml
@@ -0,0 +1,221 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2024, Zoran Krleza <zoran.krleza@true-north.hr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-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
+
+- block:
+ - name: Try to create access token in nonexisting group
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "some_nonexisting_group"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_pfail_token_status
+ always:
+ - name: Assert that token creation in nonexisting group failed
+ assert:
+ that:
+ - create_pfail_token_status is failed
+ ignore_errors: true
+
+- block:
+ - name: Try to create access token with nonvalid expires_at
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "some_nonexisting_group"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-13-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_efail_token_status
+ always:
+ - name: Assert that token creation with invalid expires_at failed
+ assert:
+ that:
+ - create_efail_token_status is failed
+ ignore_errors: true
+
+- name: Create access token
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_token_status
+- name: Assert that token creation with valid arguments is successfull
+ assert:
+ that:
+ - create_token_status is changed
+ - create_token_status.access_token.token is defined
+
+- name: Check existing access token recreate=never (default)
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: check_token_status
+- name: Assert that token creation without changes and recreate=never succeeds with status not changed
+ assert:
+ that:
+ - check_token_status is not changed
+ - check_token_status.access_token.token is not defined
+
+- name: Check existing access token with recreate=state_change
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: state_change
+ register: check_recreate_token_status
+- name: Assert that token creation without changes and recreate=state_change succeeds with status not changed
+ assert:
+ that:
+ - check_recreate_token_status is not changed
+ - check_recreate_token_status.access_token.token is not defined
+
+- block:
+ - name: Try to change existing access token with recreate=never
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: change_token_status
+ always:
+ - name: Assert that token change with recreate=never fails
+ assert:
+ that:
+ - change_token_status is failed
+ ignore_errors: true
+
+- name: Try to change existing access token with recreate=state_change
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: state_change
+ register: change_recreate_token_status
+- name: Assert that token change with recreate=state_change succeeds
+ assert:
+ that:
+ - change_recreate_token_status is changed
+ - change_recreate_token_status.access_token.token is defined
+
+- name: Try to change existing access token with recreate=always
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: always
+ register: change_recreate1_token_status
+- name: Assert that token change with recreate=always succeeds
+ assert:
+ that:
+ - change_recreate1_token_status is changed
+ - change_recreate1_token_status.access_token.token is defined
+
+- name: Revoke access token
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: absent
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: revoke_token_status
+- name: Assert that token revocation succeeds
+ assert:
+ that:
+ - revoke_token_status is changed
+
+- name: Revoke nonexisting access token
+ community.general.gitlab_group_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ group: "{{ gitlab_group_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: absent
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: revoke_token_status
+- name: Assert that token revocation succeeds with status not changed
+ assert:
+ that:
+ - revoke_token_status is not changed \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_instance_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_instance_variable/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/tasks/main.yml
new file mode 100644
index 000000000..94a81698b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/tasks/main.yml
@@ -0,0 +1,606 @@
+---
+####################################################################
+# 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_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ purge: true
+
+- name: add a variable value in check_mode
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ check_mode: true
+ register: gitlab_instance_variable_state
+
+- name: check_mode state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: apply add value from check_mode test
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: apply same value again again
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_instance_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+
+- name: change protected attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ protected: true
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: revert protected attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ protected: false
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: change masked attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ masked: true
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: revert masked attribute by not mention it
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ masked: false
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: revert again masked attribute by not mention it (idempotent)
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_instance_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+
+- name: set all attributes
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: set again all attributes (idempotent)
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_instance_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+
+- name: revert both (masked and protected) attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ protected: false
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: change a variable value in check_mode again
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ check_mode: true
+ register: gitlab_instance_variable_state
+
+- name: check_mode state must not be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+
+- name: apply again the value change from check_mode test
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_instance_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+
+- name: purge all variables again
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ purge: true
+
+- name: set two test variables
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: abc123
+ - name: SECRET_ACCESS_KEY
+ value: 321cba
+ register: gitlab_instance_variable_state
+
+- name: set two test variables state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 2
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+
+- name: re-set two test variables
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: abc123
+ - name: SECRET_ACCESS_KEY
+ value: 321cba
+ register: gitlab_instance_variable_state
+
+- name: re-set two test variables state must not be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is not changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 2
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+
+- name: edit one variable
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: changed
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: edit one variable state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 1
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 1
+ - gitlab_instance_variable_state.instance_variable.updated[0] == "ACCESS_KEY_ID"
+
+- name: append one variable
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: some
+ value: value
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 1
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 2
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+ - gitlab_instance_variable_state.instance_variable.added[0] == "some"
+
+- name: re-set all variables
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: changed
+ - name: SECRET_ACCESS_KEY
+ value: 321cba
+ - name: some
+ value: value
+ register: gitlab_instance_variable_state
+
+- name: re-set all variables state must not be changed
+ assert:
+ that:
+ - not gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 3
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+
+- name: set one variables and purge all others
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: some
+ value: value
+ purge: true
+ register: gitlab_instance_variable_state
+
+- name: set one variables and purge all others state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 1
+ - gitlab_instance_variable_state.instance_variable.removed|length == 2
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+
+- name: only one variable is left
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: some
+ value: value
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: only one variable is left state must not be changed
+ assert:
+ that:
+ - not gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 1
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched[0] == "some"
+
+- name: test integer values
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: some
+ value: 42
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 1
+
+- name: test float values
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: some
+ value: 42.23
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 1
+
+- name: delete the last left variable
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ state: absent
+ variables:
+ - name: some
+ register: gitlab_instance_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 1
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed[0] == "some"
+
+- name: add one variable with variable_type file
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: my_test_var
+ value: my_test_value
+ variable_type: file
+ purge: false
+ register: gitlab_instance_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 1
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 0
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+ # VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
+ #- gitlab_instance_variable_state.instance_variable.added[0] == "my_test_var"
+
+- name: change variable_type attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: my_test_var
+ value: my_test_value
+ variable_type: env_var
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: revert variable_type attribute
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: my_test_var
+ value: my_test_value
+ variable_type: file
+ register: gitlab_instance_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+
+- name: delete the variable_type file variable
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ state: absent
+ variables:
+ - name: my_test_var
+ register: gitlab_instance_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 1
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed[0] == "my_test_var"
+
+- name: set complete page and purge existing ones
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: page1_var01
+ value: value
+ - name: page1_var02
+ value: value
+ - name: page1_var03
+ value: value
+ - name: page1_var04
+ value: value
+ - name: page1_var05
+ value: value
+ - name: page1_var06
+ value: value
+ - name: page1_var07
+ value: value
+ - name: page1_var08
+ value: value
+ - name: page1_var09
+ value: value
+ - name: page1_var10
+ value: value
+ - name: page1_var11
+ value: value
+ - name: page1_var12
+ value: value
+ - name: page1_var13
+ value: value
+ - name: page1_var14
+ value: value
+ - name: page1_var15
+ value: value
+ - name: page1_var16
+ value: value
+ - name: page1_var17
+ value: value
+ - name: page1_var18
+ value: value
+ - name: page1_var19
+ value: value
+ - name: page1_var20
+ value: value
+ purge: true
+ register: gitlab_instance_variable_state
+
+- name: complete page added state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state is changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 20
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+
+- name: check that no variables are left
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ purge: true
+ register: gitlab_instance_variable_state
+
+- name: check that no variables are untouched state must be changed
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.added|length == 0
+ - gitlab_instance_variable_state.instance_variable.untouched|length == 0
+ - gitlab_instance_variable_state.instance_variable.removed|length == 20
+ - gitlab_instance_variable_state.instance_variable.updated|length == 0
+
+- name: throw error when state is present but no value is given
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ variables:
+ - name: no_value
+ register: gitlab_instance_variable_state
+ ignore_errors: true
+
+- name: verify fail
+ assert:
+ that:
+ - gitlab_instance_variable_state.failed
+ - gitlab_instance_variable_state is not changed
+
+- name: set a new variable to delete it later
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ purge: true
+ variables:
+ - name: delete_me
+ value: ansible
+ register: gitlab_instance_variable_state
+
+- name: verify the change
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+
+- name: delete variable without referencing its value
+ gitlab_instance_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ state: absent
+ variables:
+ - name: delete_me
+ register: gitlab_instance_variable_state
+
+- name: verify deletion
+ assert:
+ that:
+ - gitlab_instance_variable_state.changed
+ - gitlab_instance_variable_state.instance_variable.removed|length == 1
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_issue/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/aliases
new file mode 100644
index 000000000..4f4e3dcc9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_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
+
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_issue/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/defaults/main.yml
new file mode 100644
index 000000000..f94530fbf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/defaults/main.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
+
+gitlab_branch: ansible_test_branch
+gitlab_project_name: ansible_test_project
+gitlab_project_group: ansible_test_group
+gitlab_host: ansible_test_host
+gitlab_api_token: ansible_test_api_token
+gitlab_labels: ansible_test_label
+gitlab_milestone_search: ansible_test_milestone_search
+gitlab_milestone_group_id: ansible_test_milestone_group_id
+gitlab_assignee_ids: ansible_test_assignee_ids
+gitlab_description_path: ansible_test_description_path \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_issue/files/description.md b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/files/description.md
new file mode 100644
index 000000000..f0ff12a77
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/files/description.md
@@ -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
+-->
+
+### Description
+
+Issue test description \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_issue/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/tasks/main.yml
new file mode 100644
index 000000000..af1416c3d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_issue/tasks/main.yml
@@ -0,0 +1,150 @@
+---
+####################################################################
+# 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
+
+- block:
+ - name: Create {{ gitlab_project_name }} project
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ default_branch: "{{ gitlab_branch }}"
+ initialize_with_readme: true
+ state: present
+
+ - name: Create Issue
+ gitlab_issue:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ description: "Test description"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ state: present
+ title: "Ansible test issue"
+ register: gitlab_issue_create
+
+ - name: Test Issue Created
+ assert:
+ that:
+ - gitlab_issue_create is changed
+
+ - name: Create Issue ( Idempotency test )
+ gitlab_issue:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ description: "Test description"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ state: present
+ title: "Ansible test issue"
+ register: gitlab_issue_create_idempotence
+
+ - name: Test Create Issue is Idempotent
+ assert:
+ that:
+ - gitlab_issue_create_idempotence is not changed
+
+ - name: Update Issue Test ( Additions )
+ gitlab_issue:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ assignee_ids: "{{ gitlab_assignee_ids }}"
+ description_path: "{{ gitlab_description_path }}"
+ labels: "{{ gitlab_labels }}"
+ milestone_search: "{{ gitlab_milestone_search }}"
+ milestone_group_id: "{{ gitlab_milestone_group_id }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ state: present
+ title: "Ansible test issue"
+ register: gitlab_issue_update_additions
+
+ - name: Test Issue Updated ( Additions )
+ assert:
+ that:
+ - gitlab_issue_update_additions.issue.labels[0] == "{{ gitlab_labels[0] }}"
+ - gitlab_issue_update_additions.issue.assignees[0].username == "{{ gitlab_assignee_ids[0] }}"
+ - "'### Description\n\nIssue test description' in gitlab_issue_update_additions.issue.description"
+ - gitlab_issue_update_additions.issue.milestone.title == "{{ gitlab_milestone_search }}"
+
+ - name: Update Issue Test ( Persistence )
+ gitlab_issue:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ description_path: "{{ gitlab_description_path }}"
+ milestone_search: "{{ gitlab_milestone_search }}"
+ milestone_group_id: "{{ gitlab_milestone_group_id }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ state: present
+ title: "Ansible test issue"
+ register: gitlab_issue_update_persistence
+
+ - name: Test issue Not Updated ( Persistence )
+ assert:
+ that:
+ - gitlab_issue_update_persistence.issue.labels[0] == "{{ gitlab_labels[0] }}"
+ - gitlab_issue_update_persistence.issue.assignees[0].username == "{{ gitlab_assignee_ids[0] }}"
+
+ - name: Update Issue Test ( Removals )
+ gitlab_issue:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ assignee_ids: []
+ description_path: "{{ gitlab_description_path }}"
+ labels: []
+ milestone_search: ""
+ milestone_group_id: ""
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ state: present
+ title: "Ansible test issue"
+ register: gitlab_issue_update_removal
+
+ - name: Test issue updated
+ assert:
+ that:
+ - gitlab_issue_update_removal.issue.labels == []
+ - gitlab_issue_update_removal.issue.assignees == []
+ - gitlab_issue_update_removal.issue.milestone == None
+
+ - name: Delete Issue
+ gitlab_issue:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ title: "Ansible test issue"
+ state: absent
+ register: gitlab_issue_delete
+
+ - name: Test issue is deleted
+ assert:
+ that:
+ - gitlab_issue_delete is changed
+
+ always:
+ - name: Delete Issue
+ gitlab_issue:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ title: "Ansible test issue"
+ state_filter: "opened"
+ state: absent
+ register: gitlab_issue_delete
+ - name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_label/README.md b/ansible_collections/community/general/tests/integration/targets/gitlab_label/README.md
new file mode 100644
index 000000000..e27cb74c8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_label/README.md
@@ -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
+-->
+
+# Gitlab integration tests
+
+1. to run integration tests locally, I've setup a podman pod with both gitlab-ee image and the testing image
+2. gitlab's related information were taken from [here](https://docs.gitlab.com/ee/install/docker.html), about the variable it needs (hostname, ports, volumes); volumes were pre-made before launching the image
+3. image that run integration tests is started with `podman run --rm -it --pod <pod_name> --name <image_name> --network=host --volume <path_to_git_repo>/ansible_community/community.general:<container_path_to>/workspace/ansible_collections/community/general quay.io/ansible/azure-pipelines-test-container:4.0.1`
+4. into the testing image, run
+```sh
+pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
+cd <container_path_to>/workspace/ansible_collections/community/general
+ansible-test integration gitlab_label -vvv
+```
+
+While debugging with `q` package, open a second terminal and run `podman exec -it <image_name> /bin/bash` and inside it do `tail -f /tmp/q` .
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_label/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_label/aliases
new file mode 100644
index 000000000..4f4e3dcc9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_label/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
+
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_label/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_label/defaults/main.yml
new file mode 100644
index 000000000..315cbd77f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_label/defaults/main.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
+
+gitlab_project_name: ansible_test_project
+gitlab_host: ansible_test_host
+gitlab_api_token: ansible_test_api_token
+gitlab_project_group: ansible_test_group
+gitlab_branch: ansible_test_branch
+gitlab_first_label: ansible_test_label
+gitlab_first_label_color: "#112233"
+gitlab_first_label_description: "label description"
+gitlab_first_label_priority: 10
+gitlab_second_label: ansible_test_second_label
+gitlab_second_label_color: "#445566"
+gitlab_second_label_new_name: ansible_test_second_label_new_name \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_label/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_label/tasks/main.yml
new file mode 100644
index 000000000..880b72ceb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_label/tasks/main.yml
@@ -0,0 +1,463 @@
+---
+####################################################################
+# 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
+
+- block:
+###
+### Group label
+###
+
+ - name: Create {{ gitlab_project_group }}
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_group }}"
+ state: present
+
+ - name: Purge all group labels for check_mode test
+ gitlab_label:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+
+ - name: Group label - Add a label in check_mode
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ check_mode: true
+ register: gitlab_group_label_state
+
+ - name: Group label - Check_mode state must be changed
+ assert:
+ that:
+ - gitlab_group_label_state is changed
+
+ - name: Group label - Create label {{ gitlab_first_label }} and {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_first_label_color }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_group_label_create
+
+ - name: Group label - Test Label Created
+ assert:
+ that:
+ - gitlab_group_label_create is changed
+ - gitlab_group_label_create.labels.added|length == 2
+ - gitlab_group_label_create.labels.untouched|length == 0
+ - gitlab_group_label_create.labels.removed|length == 0
+ - gitlab_group_label_create.labels.updated|length == 0
+ - gitlab_group_label_create.labels.added[0] == "{{ gitlab_first_label }}"
+ - gitlab_group_label_create.labels.added[1] == "{{ gitlab_second_label }}"
+
+ - name: Group label - Create Label ( Idempotency test )
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_first_label_color }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ state: present
+ register: gitlab_group_label_create_idempotence
+
+ - name: Group label - Test Create Label is Idempotent
+ assert:
+ that:
+ - gitlab_group_label_create_idempotence is not changed
+
+ - name: Group label - Update Label {{ gitlab_first_label }} changing color
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_group_label_update
+
+ - name: Group label - Test Label Updated
+ assert:
+ that:
+ - gitlab_group_label_update.labels.added|length == 0
+ - gitlab_group_label_update.labels.untouched|length == 0
+ - gitlab_group_label_update.labels.removed|length == 0
+ - gitlab_group_label_update.labels.updated|length == 1
+ - gitlab_group_label_update.labels.updated[0] == "{{ gitlab_first_label }}"
+
+ - name: Group label - Change label {{ gitlab_second_label }} name to {{ gitlab_second_label_new_name }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ new_name: "{{ gitlab_second_label_new_name }}"
+ state: present
+ register: gitlab_group_label_new_name
+
+ - name: Group label - Test Label name changed
+ assert:
+ that:
+ - gitlab_group_label_new_name.labels.added|length == 0
+ - gitlab_group_label_new_name.labels.untouched|length == 0
+ - gitlab_group_label_new_name.labels.removed|length == 0
+ - gitlab_group_label_new_name.labels.updated|length == 1
+ - gitlab_group_label_new_name.labels.updated[0] == "{{ gitlab_second_label }}"
+
+ - name: Group label - Change label name back to {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_second_label_new_name }}"
+ new_name: "{{ gitlab_second_label }}"
+ state: present
+ register: gitlab_group_label_orig_name
+
+ - name: Group label - Test Label name changed back
+ assert:
+ that:
+ - gitlab_group_label_orig_name.labels.added|length == 0
+ - gitlab_group_label_orig_name.labels.untouched|length == 0
+ - gitlab_group_label_orig_name.labels.removed|length == 0
+ - gitlab_group_label_orig_name.labels.updated|length == 1
+ - gitlab_group_label_orig_name.labels.updated[0] == "{{ gitlab_second_label_new_name }}"
+
+ - name: Group label - Update Label Test ( Additions )
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ state: present
+ register: gitlab_group_label_update_additions
+
+ - name: Group label - Test Label Updated ( Additions )
+ assert:
+ that:
+ - gitlab_group_label_update_additions.labels.added|length == 0
+ - gitlab_group_label_update_additions.labels.untouched|length == 0
+ - gitlab_group_label_update_additions.labels.removed|length == 0
+ - gitlab_group_label_update_additions.labels.updated|length == 1
+ - gitlab_group_label_update_additions.labels.updated[0] == "{{ gitlab_second_label }}"
+
+ - name: Group label - Delete Label {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ state: absent
+ register: gitlab_group_label_delete
+
+ - name: Group label - Test label is deleted
+ assert:
+ that:
+ - gitlab_group_label_delete is changed
+ - gitlab_group_label_delete.labels.added|length == 0
+ - gitlab_group_label_delete.labels.untouched|length == 0
+ - gitlab_group_label_delete.labels.removed|length == 1
+ - gitlab_group_label_delete.labels.updated|length == 0
+ - gitlab_group_label_delete.labels.removed[0] == "{{ gitlab_second_label }}"
+
+ - name: Group label - Create label {{ gitlab_second_label }} again purging the other
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_group_label_create_purging
+
+ - name: Group label - Test Label Created again
+ assert:
+ that:
+ - gitlab_group_label_create_purging is changed
+ - gitlab_group_label_create_purging.labels.added|length == 1
+ - gitlab_group_label_create_purging.labels.untouched|length == 0
+ - gitlab_group_label_create_purging.labels.removed|length == 1
+ - gitlab_group_label_create_purging.labels.updated|length == 0
+ - gitlab_group_label_create_purging.labels.added[0] == "{{ gitlab_second_label }}"
+ - gitlab_group_label_create_purging.labels.removed[0] == "{{ gitlab_first_label }}"
+
+###
+### Project label
+###
+
+ - name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ default_branch: "{{ gitlab_branch }}"
+ initialize_with_readme: true
+ state: present
+
+ - name: Purge all labels for check_mode test
+ gitlab_label:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+
+ - name: Add a label in check_mode
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ check_mode: true
+ register: gitlab_first_label_state
+
+ - name: Check_mode state must be changed
+ assert:
+ that:
+ - gitlab_first_label_state is changed
+
+ - name: Create label {{ gitlab_first_label }} and {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_first_label_color }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_first_label_create
+
+ - name: Test Label Created
+ assert:
+ that:
+ - gitlab_first_label_create is changed
+ - gitlab_first_label_create.labels.added|length == 2
+ - gitlab_first_label_create.labels.untouched|length == 0
+ - gitlab_first_label_create.labels.removed|length == 0
+ - gitlab_first_label_create.labels.updated|length == 0
+ - gitlab_first_label_create.labels.added[0] == "{{ gitlab_first_label }}"
+ - gitlab_first_label_create.labels.added[1] == "{{ gitlab_second_label }}"
+
+ - name: Create Label ( Idempotency test )
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_first_label_color }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ state: present
+ register: gitlab_first_label_create_idempotence
+
+ - name: Test Create Label is Idempotent
+ assert:
+ that:
+ - gitlab_first_label_create_idempotence is not changed
+
+ - name: Update Label {{ gitlab_first_label }} changing color
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_first_label_update
+
+ - name: Test Label Updated
+ assert:
+ that:
+ - gitlab_first_label_update.labels.added|length == 0
+ - gitlab_first_label_update.labels.untouched|length == 0
+ - gitlab_first_label_update.labels.removed|length == 0
+ - gitlab_first_label_update.labels.updated|length == 1
+ - gitlab_first_label_update.labels.updated[0] == "{{ gitlab_first_label }}"
+
+ - name: Change label {{ gitlab_second_label }} name to {{ gitlab_second_label_new_name }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ new_name: "{{ gitlab_second_label_new_name }}"
+ state: present
+ register: gitlab_first_label_new_name
+
+ - name: Test Label name changed
+ assert:
+ that:
+ - gitlab_first_label_new_name.labels.added|length == 0
+ - gitlab_first_label_new_name.labels.untouched|length == 0
+ - gitlab_first_label_new_name.labels.removed|length == 0
+ - gitlab_first_label_new_name.labels.updated|length == 1
+ - gitlab_first_label_new_name.labels.updated[0] == "{{ gitlab_second_label }}"
+
+ - name: Change label name back to {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_second_label_new_name }}"
+ new_name: "{{ gitlab_second_label }}"
+ state: present
+ register: gitlab_first_label_orig_name
+
+ - name: Test Label name changed back
+ assert:
+ that:
+ - gitlab_first_label_orig_name.labels.added|length == 0
+ - gitlab_first_label_orig_name.labels.untouched|length == 0
+ - gitlab_first_label_orig_name.labels.removed|length == 0
+ - gitlab_first_label_orig_name.labels.updated|length == 1
+ - gitlab_first_label_orig_name.labels.updated[0] == "{{ gitlab_second_label_new_name }}"
+
+ - name: Update Label Test ( Additions )
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ description: "{{ gitlab_first_label_description }}"
+ priority: "{{ gitlab_first_label_priority }}"
+ state: present
+ register: gitlab_first_label_update_additions
+
+ - name: Test Label Updated ( Additions )
+ assert:
+ that:
+ - gitlab_first_label_update_additions.labels.added|length == 0
+ - gitlab_first_label_update_additions.labels.untouched|length == 0
+ - gitlab_first_label_update_additions.labels.removed|length == 0
+ - gitlab_first_label_update_additions.labels.updated|length == 1
+ - gitlab_first_label_update_additions.labels.updated[0] == "{{ gitlab_second_label }}"
+
+ - name: Delete Label {{ gitlab_second_label }}
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ state: absent
+ register: gitlab_first_label_delete
+
+ - name: Test label is deleted
+ assert:
+ that:
+ - gitlab_first_label_delete is changed
+ - gitlab_first_label_delete.labels.added|length == 0
+ - gitlab_first_label_delete.labels.untouched|length == 0
+ - gitlab_first_label_delete.labels.removed|length == 1
+ - gitlab_first_label_delete.labels.updated|length == 0
+ - gitlab_first_label_delete.labels.removed[0] == "{{ gitlab_second_label }}"
+
+ - name: Create label {{ gitlab_second_label }} again purging the other
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+ labels:
+ - name: "{{ gitlab_second_label }}"
+ color: "{{ gitlab_second_label_color }}"
+ state: present
+ register: gitlab_first_label_create_purging
+
+ - name: Test Label Created again
+ assert:
+ that:
+ - gitlab_first_label_create_purging is changed
+ - gitlab_first_label_create_purging.labels.added|length == 1
+ - gitlab_first_label_create_purging.labels.untouched|length == 0
+ - gitlab_first_label_create_purging.labels.removed|length == 1
+ - gitlab_first_label_create_purging.labels.updated|length == 0
+ - gitlab_first_label_create_purging.labels.added[0] == "{{ gitlab_second_label }}"
+ - gitlab_first_label_create_purging.labels.removed[0] == "{{ gitlab_first_label }}"
+
+ always:
+ - name: Delete Labels
+ gitlab_label:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+ labels:
+ - name: "{{ gitlab_first_label }}"
+ - name: "{{ gitlab_second_label }}"
+ state: absent
+ register: gitlab_first_label_always_delete
+
+ - name: Test label are deleted
+ assert:
+ that:
+ - gitlab_first_label_always_delete is changed
+ - gitlab_first_label_always_delete.labels.added|length == 0
+ - gitlab_first_label_always_delete.labels.untouched|length == 0
+ - gitlab_first_label_always_delete.labels.removed|length > 0
+ - gitlab_first_label_always_delete.labels.updated|length == 0
+
+ - name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ state: absent
+
+ - name: Clean up {{ gitlab_project_group }}
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_group }}"
+ state: absent \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/aliases
new file mode 100644
index 000000000..4f4e3dcc9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/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
+
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/defaults/main.yml
new file mode 100644
index 000000000..eb27b0b68
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/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
+
+gitlab_source_branch: ansible_test_source_branch
+gitlab_target_branch: ansible_test_target_project
+gitlab_project_name: ansible_test_project
+gitlab_project_group: ansible_test_group
+gitlab_host: ansible_test_host
+gitlab_api_token: ansible_test_api_token
+gitlab_labels: ansible_test_label
+gitlab_assignee_ids: ansible_test_assignee_ids
+gitlab_description_path: ansible_test_description_path \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/files/description.md b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/files/description.md
new file mode 100644
index 000000000..3f662eff8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/files/description.md
@@ -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
+-->
+
+### Description
+
+Merge Request test description \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/tasks/main.yml
new file mode 100644
index 000000000..18da900a2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/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
+
+- block:
+ - name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ default_branch: "{{ gitlab_target_branch }}"
+ initialize_with_readme: true
+ state: present
+
+ - name: Create branch {{ gitlab_source_branch }}
+ gitlab_branch:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ branch: "{{ gitlab_source_branch }}"
+ ref_branch: "{{ gitlab_target_branch }}"
+ state: present
+
+ - name: Create Merge Request
+ gitlab_merge_request:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ source_branch: "{{gitlab_source_branch}}"
+ target_branch: "{{gitlab_target_branch}}"
+ title: "Ansible test merge request"
+ description: "Test description"
+ labels: ""
+ state_filter: "opened"
+ assignee_ids: ""
+ reviewer_ids: ""
+ remove_source_branch: True
+ state: present
+ register: gitlab_merge_request_create
+
+ - name: Test Merge Request Created
+ assert:
+ that:
+ - gitlab_merge_request_create is changed
+
+ - name: Create Merge Request ( Idempotency test )
+ gitlab_merge_request:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ source_branch: "{{gitlab_source_branch}}"
+ target_branch: "{{gitlab_target_branch}}"
+ title: "Ansible test merge request"
+ description: "Test description"
+ labels: ""
+ state_filter: "opened"
+ assignee_ids: ""
+ reviewer_ids: ""
+ remove_source_branch: True
+ state: present
+ register: gitlab_merge_request_create_idempotence
+
+ - name: Test module is idempotent
+ assert:
+ that:
+ - gitlab_merge_request_create_idempotence is not changed
+
+ - name: Update Merge Request Test
+ gitlab_merge_request:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ source_branch: "{{gitlab_source_branch}}"
+ target_branch: "{{gitlab_target_branch}}"
+ title: "Ansible test merge request"
+ description_path: "{{gitlab_description_path}}"
+ labels: "{{ gitlab_labels }}"
+ state_filter: "opened"
+ assignee_ids: "{{ gitlab_assignee_ids }}"
+ reviewer_ids: ""
+ remove_source_branch: True
+ state: present
+ register: gitlab_merge_request_udpate
+
+ - name: Test merge request updated
+ assert:
+ that:
+ - gitlab_merge_request_udpate.mr.labels[0] == "{{ gitlab_labels }}"
+ - gitlab_merge_request_udpate.mr.assignees[0].username == "{{ gitlab_assignee_ids }}"
+ - "'### Description\n\nMerge Request test description' in gitlab_merge_request_udpate.mr.description"
+
+ - name: Delete Merge Request
+ gitlab_merge_request:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ source_branch: "{{gitlab_source_branch}}"
+ target_branch: "{{gitlab_target_branch}}"
+ title: "Ansible test merge request"
+ state: absent
+ register: gitlab_merge_request_delete
+
+ - name: Test merge request is deleted
+ assert:
+ that:
+ - gitlab_merge_request_delete is changed
+
+ always:
+ - name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/README.md b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/README.md
new file mode 100644
index 000000000..95bb3410b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/README.md
@@ -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
+-->
+
+# Gitlab integration tests
+
+1. to run integration tests locally, I've setup a podman pod with both gitlab-ee image and the testing image
+2. gitlab's related information were taken from [here](https://docs.gitlab.com/ee/install/docker.html), about the variable it needs (hostname, ports, volumes); volumes were pre-made before launching the image
+3. image that run integration tests is started with `podman run --rm -it --pod <pod_name> --name <image_name> --network=host --volume <path_to_git_repo>/ansible_community/community.general:<container_path_to>/workspace/ansible_collections/community/general quay.io/ansible/azure-pipelines-test-container:4.0.1`
+4. into the testing image, run
+```sh
+pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
+cd <container_path_to>/workspace/ansible_collections/community/general
+ansible-test integration gitlab_milestone -vvv
+```
+
+While debugging with `q` package, open a second terminal and run `podman exec -it <image_name> /bin/bash` and inside it do `tail -f /tmp/q` .
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/aliases
new file mode 100644
index 000000000..1d485e509
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/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
+
+gitlab/ci
+disabled \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/defaults/main.yml
new file mode 100644
index 000000000..d11001295
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/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_project_name: ansible_test_project
+gitlab_host: ansible_test_host
+gitlab_api_token: ansible_test_api_token
+gitlab_project_group: ansible_test_group
+gitlab_branch: ansible_test_branch
+gitlab_first_milestone: ansible_test_milestone
+gitlab_first_milestone_description: "milestone description"
+gitlab_first_milestone_start_date: "2024-01-01"
+gitlab_first_milestone_due_date: "2024-12-31"
+gitlab_first_milestone_new_start_date: "2024-05-01"
+gitlab_first_milestone_new_due_date: "2024-10-31"
+gitlab_second_milestone: ansible_test_second_milestone
+gitlab_second_milestone_description: "new milestone"
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/tasks/main.yml
new file mode 100644
index 000000000..ce78c2eef
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_milestone/tasks/main.yml
@@ -0,0 +1,388 @@
+---
+####################################################################
+# 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
+
+- block:
+###
+### Group milestone
+###
+ - name: Create {{ gitlab_project_group }}
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_group }}"
+ state: present
+
+ - name: Purge all group milestones for check_mode test
+ gitlab_milestone:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+
+ - name: Group milestone - Add a milestone in check_mode
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ check_mode: true
+ register: gitlab_group_milestone_state
+
+ - name: Group milestone - Check_mode state must be changed
+ assert:
+ that:
+ - gitlab_group_milestone_state is changed
+
+ - name: Purge all group milestones for project milestone test - cannot exist with same name
+ gitlab_milestone:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+ register: gitlab_group_milestone_purged
+
+ - name: Group milestone - Create milestone {{ gitlab_first_milestone }} and {{ gitlab_second_milestone }}
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_start_date }}"
+ due_date: "{{ gitlab_first_milestone_due_date }}"
+ - title: "{{ gitlab_second_milestone }}"
+ state: present
+ register: gitlab_group_milestone_create
+
+ - name: Group milestone - Test milestone Created
+ assert:
+ that:
+ - gitlab_group_milestone_create is changed
+ - gitlab_group_milestone_create.milestones.added|length == 2
+ - gitlab_group_milestone_create.milestones.untouched|length == 0
+ - gitlab_group_milestone_create.milestones.removed|length == 0
+ - gitlab_group_milestone_create.milestones.updated|length == 0
+ - gitlab_group_milestone_create.milestones.added[0] == "{{ gitlab_first_milestone }}"
+ - gitlab_group_milestone_create.milestones.added[1] == "{{ gitlab_second_milestone }}"
+
+ - name: Group milestone - Create milestone ( Idempotency test )
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_start_date }}"
+ due_date: "{{ gitlab_first_milestone_due_date }}"
+ state: present
+ register: gitlab_group_milestone_create_idempotence
+
+ - name: Group milestone - Test Create milestone is Idempotent
+ assert:
+ that:
+ - gitlab_group_milestone_create_idempotence is not changed
+
+ - name: Group milestone - Update milestone {{ gitlab_first_milestone }} changing dates
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_new_start_date }}"
+ due_date: "{{ gitlab_first_milestone_new_due_date }}"
+ state: present
+ register: gitlab_group_milestone_update
+
+ - name: Group milestone - Test milestone Updated
+ assert:
+ that:
+ - gitlab_group_milestone_update.milestones.added|length == 0
+ - gitlab_group_milestone_update.milestones.untouched|length == 0
+ - gitlab_group_milestone_update.milestones.removed|length == 0
+ - gitlab_group_milestone_update.milestones.updated|length == 1
+ - gitlab_group_milestone_update.milestones.updated[0] == "{{ gitlab_first_milestone }}"
+
+ - name: Group milestone - Update milestone Test ( Additions )
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ description: "{{ gitlab_first_milestone_description }}"
+ state: present
+ register: gitlab_group_milestone_update_additions
+
+ - name: Group milestone - Test milestone Updated ( Additions )
+ assert:
+ that:
+ - gitlab_group_milestone_update_additions.milestones.added|length == 0
+ - gitlab_group_milestone_update_additions.milestones.untouched|length == 0
+ - gitlab_group_milestone_update_additions.milestones.removed|length == 0
+ - gitlab_group_milestone_update_additions.milestones.updated|length == 1
+ - gitlab_group_milestone_update_additions.milestones.updated[0] == "{{ gitlab_second_milestone }}"
+
+ - name: Group milestone - Delete milestone {{ gitlab_second_milestone }}
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ state: absent
+ register: gitlab_group_milestone_delete
+
+ - name: Group milestone - Test milestone is deleted
+ assert:
+ that:
+ - gitlab_group_milestone_delete is changed
+ - gitlab_group_milestone_delete.milestones.added|length == 0
+ - gitlab_group_milestone_delete.milestones.untouched|length == 0
+ - gitlab_group_milestone_delete.milestones.removed|length == 1
+ - gitlab_group_milestone_delete.milestones.updated|length == 0
+ - gitlab_group_milestone_delete.milestones.removed[0] == "{{ gitlab_second_milestone }}"
+
+ - name: Group milestone - Create group milestone {{ gitlab_second_milestone }} again purging the other
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ state: present
+ register: gitlab_group_milestone_create_purging
+
+ - name: Group milestone - Test milestone Created again
+ assert:
+ that:
+ - gitlab_group_milestone_create_purging is changed
+ - gitlab_group_milestone_create_purging.milestones.added|length == 1
+ - gitlab_group_milestone_create_purging.milestones.untouched|length == 0
+ - gitlab_group_milestone_create_purging.milestones.removed|length == 1
+ - gitlab_group_milestone_create_purging.milestones.updated|length == 0
+ - gitlab_group_milestone_create_purging.milestones.added[0] == "{{ gitlab_second_milestone }}"
+ - gitlab_group_milestone_create_purging.milestones.removed[0] == "{{ gitlab_first_milestone }}"
+
+###
+### Project milestone
+###
+ - name: Purge all group milestones for project milestone test - cannot exist with same name
+ gitlab_milestone:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ group: "{{ gitlab_project_group }}"
+ purge: true
+ register: gitlab_group_milestone_purged
+
+ - name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ default_branch: "{{ gitlab_branch }}"
+ initialize_with_readme: true
+ state: present
+
+ - name: Purge all milestones for check_mode test
+ gitlab_milestone:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+
+ - name: Add a milestone in check_mode
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ description: "{{ gitlab_second_milestone_description }}"
+ check_mode: true
+ register: gitlab_first_milestone_state
+
+ - name: Check_mode state must be changed
+ assert:
+ that:
+ - gitlab_first_milestone_state is changed
+
+ - name: Create milestone {{ gitlab_first_milestone }} and {{ gitlab_second_milestone }}
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_start_date }}"
+ due_date: "{{ gitlab_first_milestone_due_date }}"
+ - title: "{{ gitlab_second_milestone }}"
+ state: present
+ register: gitlab_milestones_create
+
+ - name: Test milestone Created
+ assert:
+ that:
+ - gitlab_milestones_create is changed
+ - gitlab_milestones_create.milestones.added|length == 2
+ - gitlab_milestones_create.milestones.untouched|length == 0
+ - gitlab_milestones_create.milestones.removed|length == 0
+ - gitlab_milestones_create.milestones.updated|length == 0
+ - gitlab_milestones_create.milestones.added[0] == "{{ gitlab_first_milestone }}"
+ - gitlab_milestones_create.milestones.added[1] == "{{ gitlab_second_milestone }}"
+
+ - name: Create milestone ( Idempotency test )
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_start_date }}"
+ due_date: "{{ gitlab_first_milestone_due_date }}"
+ state: present
+ register: gitlab_first_milestone_create_idempotence
+
+ - name: Test Create milestone is Idempotent
+ assert:
+ that:
+ - gitlab_first_milestone_create_idempotence is not changed
+
+ - name: Update milestone {{ gitlab_first_milestone }} changing dates
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ start_date: "{{ gitlab_first_milestone_new_start_date }}"
+ due_date: "{{ gitlab_first_milestone_new_due_date }}"
+ state: present
+ register: gitlab_first_milestone_update
+
+ - name: Test milestone Updated
+ assert:
+ that:
+ - gitlab_first_milestone_update.milestones.added|length == 0
+ - gitlab_first_milestone_update.milestones.untouched|length == 0
+ - gitlab_first_milestone_update.milestones.removed|length == 0
+ - gitlab_first_milestone_update.milestones.updated|length == 1
+ - gitlab_first_milestone_update.milestones.updated[0] == "{{ gitlab_first_milestone }}"
+
+ - name: Update milestone Test ( Additions )
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ description: "{{ gitlab_second_milestone_description }}"
+ state: present
+ register: gitlab_first_milestone_update_additions
+
+ - name: Test milestone Updated ( Additions )
+ assert:
+ that:
+ - gitlab_first_milestone_update_additions.milestones.added|length == 0
+ - gitlab_first_milestone_update_additions.milestones.untouched|length == 0
+ - gitlab_first_milestone_update_additions.milestones.removed|length == 0
+ - gitlab_first_milestone_update_additions.milestones.updated|length == 1
+ - gitlab_first_milestone_update_additions.milestones.updated[0] == "{{ gitlab_second_milestone }}"
+
+ - name: Delete milestone {{ gitlab_second_milestone }}
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ state: absent
+ register: gitlab_first_milestone_delete
+
+ - name: Test milestone is deleted
+ assert:
+ that:
+ - gitlab_first_milestone_delete is changed
+ - gitlab_first_milestone_delete.milestones.added|length == 0
+ - gitlab_first_milestone_delete.milestones.untouched|length == 0
+ - gitlab_first_milestone_delete.milestones.removed|length == 1
+ - gitlab_first_milestone_delete.milestones.updated|length == 0
+ - gitlab_first_milestone_delete.milestones.removed[0] == "{{ gitlab_second_milestone }}"
+
+ - name: Create milestone {{ gitlab_second_milestone }} again purging the other
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+ milestones:
+ - title: "{{ gitlab_second_milestone }}"
+ state: present
+ register: gitlab_first_milestone_create_purging
+
+ - name: Test milestone Created again
+ assert:
+ that:
+ - gitlab_first_milestone_create_purging is changed
+ - gitlab_first_milestone_create_purging.milestones.added|length == 1
+ - gitlab_first_milestone_create_purging.milestones.untouched|length == 0
+ - gitlab_first_milestone_create_purging.milestones.removed|length == 1
+ - gitlab_first_milestone_create_purging.milestones.updated|length == 0
+ - gitlab_first_milestone_create_purging.milestones.added[0] == "{{ gitlab_second_milestone }}"
+ - gitlab_first_milestone_create_purging.milestones.removed[0] == "{{ gitlab_first_milestone }}"
+
+ always:
+ - name: Delete milestones
+ gitlab_milestone:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_host }}"
+ project: "{{ gitlab_project_group }}/{{ gitlab_project_name }}"
+ purge: true
+ milestones:
+ - title: "{{ gitlab_first_milestone }}"
+ - title: "{{ gitlab_second_milestone }}"
+ state: absent
+ register: gitlab_first_milestone_always_delete
+
+ - name: Test milestone are deleted
+ assert:
+ that:
+ - gitlab_first_milestone_always_delete is changed
+ - gitlab_first_milestone_always_delete.milestones.added|length == 0
+ - gitlab_first_milestone_always_delete.milestones.untouched|length == 0
+ - gitlab_first_milestone_always_delete.milestones.removed|length > 0
+ - gitlab_first_milestone_always_delete.milestones.updated|length == 0
+
+ - name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ group: "{{ gitlab_project_group }}"
+ state: absent
+
+ - name: Clean up {{ gitlab_project_group }}
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: true
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_group }}"
+ state: absent \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/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_access_token/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/defaults/main.yml
new file mode 100644
index 000000000..579584d62
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/defaults/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 #
+####################################################################
+
+# Copyright (c) 2024, Zoran Krleza <zoran.krleza@true-north.hr>
+# GNU General Public License v3.0+ (see LICENSES/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:
+gitlab_api_url:
+gitlab_validate_certs: false
+gitlab_project_name:
+gitlab_token_name:
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/tasks/main.yml
new file mode 100644
index 000000000..c3125d740
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/tasks/main.yml
@@ -0,0 +1,221 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2024, Zoran Krleza <zoran.krleza@true-north.hr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-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
+
+- block:
+ - name: Try to create access token in nonexisting project
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "some_nonexisting_project"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_pfail_token_status
+ always:
+ - name: Assert that token creation in nonexisting project failed
+ assert:
+ that:
+ - create_pfail_token_status is failed
+ ignore_errors: true
+
+- block:
+ - name: Try to create access token with nonvalid expires_at
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "some_nonexisting_project"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-13-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_efail_token_status
+ always:
+ - name: Assert that token creation with invalid expires_at failed
+ assert:
+ that:
+ - create_efail_token_status is failed
+ ignore_errors: true
+
+- name: Create access token
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: create_token_status
+- name: Assert that token creation with valid arguments is successfull
+ assert:
+ that:
+ - create_token_status is changed
+ - create_token_status.access_token.token is defined
+
+- name: Check existing access token recreate=never (default)
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: check_token_status
+- name: Assert that token creation without changes and recreate=never succeeds with status not changed
+ assert:
+ that:
+ - check_token_status is not changed
+ - check_token_status.access_token.token is not defined
+
+- name: Check existing access token with recreate=state_change
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: state_change
+ register: check_recreate_token_status
+- name: Assert that token creation without changes and recreate=state_change succeeds with status not changed
+ assert:
+ that:
+ - check_recreate_token_status is not changed
+ - check_recreate_token_status.access_token.token is not defined
+
+- block:
+ - name: Try to change existing access token with recreate=never
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: change_token_status
+ always:
+ - name: Assert that token change with recreate=never fails
+ assert:
+ that:
+ - change_token_status is failed
+ ignore_errors: true
+
+- name: Try to change existing access token with recreate=state_change
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: state_change
+ register: change_recreate_token_status
+- name: Assert that token change with recreate=state_change succeeds
+ assert:
+ that:
+ - change_recreate_token_status is changed
+ - change_recreate_token_status.access_token.token is defined
+
+- name: Try to change existing access token with recreate=always
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: present
+ expires_at: '2025-01-01'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ recreate: always
+ register: change_recreate1_token_status
+- name: Assert that token change with recreate=always succeeds
+ assert:
+ that:
+ - change_recreate1_token_status is changed
+ - change_recreate1_token_status.access_token.token is defined
+
+- name: Revoke access token
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: absent
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: revoke_token_status
+- name: Assert that token revocation succeeds
+ assert:
+ that:
+ - revoke_token_status is changed
+
+- name: Revoke nonexisting access token
+ community.general.gitlab_project_access_token:
+ api_token: "{{ gitlab_api_token }}"
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: "{{ gitlab_validate_certs }}"
+ project: "{{ gitlab_project_name }}"
+ name: "{{ gitlab_token_name }}"
+ state: absent
+ expires_at: '2024-12-31'
+ access_level: developer
+ scopes:
+ - api
+ - read_api
+ register: revoke_token_status
+- name: Assert that token revocation succeeds with status not changed
+ assert:
+ that:
+ - revoke_token_status is not changed \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/aliases b/ansible_collections/community/general/tests/integration/targets/homebrew/aliases
index 11bb9a086..bd478505d 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/aliases
@@ -7,4 +7,3 @@ skip/aix
skip/freebsd
skip/rhel
skip/docker
-skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml
new file mode 100644
index 000000000..42d3515bf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.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: kitty
+
+ 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/tasks/formulae.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml
new file mode 100644
index 000000000..1db3ef1a6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.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/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
index 1db3ef1a6..f5479917e 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
@@ -9,91 +9,9 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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:
+ - include_tasks: 'formulae.yml'
+
+- when: ansible_distribution in ['MacOSX']
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
+ - include_tasks: 'casks.yml'
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases
index 11bb9a086..bd478505d 100644
--- a/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases
@@ -7,4 +7,3 @@ skip/aix
skip/freebsd
skip/rhel
skip/docker
-skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/homectl/aliases b/ansible_collections/community/general/tests/integration/targets/homectl/aliases
index b87db2e43..ea9b44230 100644
--- a/ansible_collections/community/general/tests/integration/targets/homectl/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/homectl/aliases
@@ -9,3 +9,5 @@ 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/
+skip/rhel9.2 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
+skip/rhel9.3 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
diff --git a/ansible_collections/community/general/tests/integration/targets/htpasswd/aliases b/ansible_collections/community/general/tests/integration/targets/htpasswd/aliases
new file mode 100644
index 000000000..e3339b210
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/htpasswd/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
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/htpasswd/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/htpasswd/handlers/main.yml
new file mode 100644
index 000000000..6befa0cd3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/htpasswd/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 passlib
+ ansible.builtin.pip:
+ name: passlib
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/htpasswd/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/htpasswd/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/htpasswd/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/htpasswd/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/htpasswd/tasks/main.yml
new file mode 100644
index 000000000..7b5dc3c51
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/htpasswd/tasks/main.yml
@@ -0,0 +1,83 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 passlib
+ ansible.builtin.pip:
+ name: passlib
+ notify: remove passlib
+
+- name: add bob (check mode)
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ password: c00lbob
+ check_mode: true
+ register: add_bob_check
+
+- name: add bob
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ password: c00lbob
+ register: add_bob
+
+- name: add bob (idempotency)
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ password: c00lbob
+ register: add_bob_idempot
+
+- name: add bob new password
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ password: SUPERsecret
+ register: add_bob_newpw
+
+- name: add bob new password (idempotency)
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ password: SUPERsecret
+ register: add_bob_newpw_idempot
+
+- name: test add bob assertions
+ ansible.builtin.assert:
+ that:
+ - add_bob_check is changed
+ - add_bob is changed
+ - add_bob_idempot is not changed
+ - add_bob_newpw is changed
+ - add_bob_newpw_idempot is not changed
+
+- name: remove bob (check mode)
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ state: absent
+ check_mode: true
+ register: del_bob_check
+
+- name: remove bob
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ state: absent
+ register: del_bob
+
+- name: remove bob (idempotency)
+ community.general.htpasswd:
+ path: "{{ htpasswd_path }}"
+ name: bob
+ state: absent
+ register: del_bob_idempot
+
+- name: test remove bob assertions
+ ansible.builtin.assert:
+ that:
+ - del_bob_check is changed
+ - del_bob is changed
+ - del_bob_idempot is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/htpasswd/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/htpasswd/vars/main.yml
new file mode 100644
index 000000000..ff81959c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/htpasswd/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
+
+htpasswd_path: "{{ remote_tmp_dir }}/dot_htpasswd"
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
index 11c5bf3b2..0ed3c2817 100644
--- 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
@@ -38,3 +38,15 @@
- name: include tasks to test regressions
include_tasks: tests/03-encoding.yml
+
+ - name: include tasks to test symlink handling
+ include_tasks: tests/04-symlink.yml
+
+ - name: include tasks to test ignore_spaces
+ include_tasks: tests/05-ignore_spaces.yml
+
+ - name: include tasks to test modify_inactive_option
+ include_tasks: tests/06-modify_inactive_option.yml
+
+ - name: include tasks to test optional spaces in section headings
+ include_tasks: tests/07-section_name_spaces.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
index c619e937a..f36fd54c5 100644
--- 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
@@ -3,7 +3,7 @@
# GNU General Public License v3.0+ (see LICENSES/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
+## basics
- name: test-basic 1 - specify both "value" and "values" and fail
ini_file:
@@ -39,4 +39,4 @@
that:
- result_basic_2 is not changed
- result_basic_2 is failed
- - result_basic_2.msg == "Destination {{ non_existing_file }} does not exist!"
+ - 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/04-symlink.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/04-symlink.yml
new file mode 100644
index 000000000..7e83a010d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/04-symlink.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
+
+- block: &prepare
+ - name: Create the final file
+ ansible.builtin.copy:
+ content: |
+ [main]
+ foo=BAR
+ dest: "{{ remote_tmp_dir }}/my_original_file.ini"
+ - name: Clean up symlink.ini
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}/symlink.ini"
+ state: absent
+ - name: Create a symbolic link
+ ansible.builtin.file:
+ src: my_original_file.ini
+ dest: "{{ remote_tmp_dir }}/symlink.ini"
+ state: link
+
+- name: Set the proxy key on the symlink which will be converted as a file
+ community.general.ini_file:
+ path: "{{ remote_tmp_dir }}/symlink.ini"
+ section: main
+ option: proxy
+ value: 'http://proxy.myorg.org:3128'
+- name: Set the proxy key on the final file that is still unchanged
+ community.general.ini_file:
+ path: "{{ remote_tmp_dir }}/my_original_file.ini"
+ section: main
+ option: proxy
+ value: 'http://proxy.myorg.org:3128'
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result is changed
+
+# With follow
+- block: *prepare
+- name: Set the proxy key on the symlink which will be preserved
+ community.general.ini_file:
+ path: "{{ remote_tmp_dir }}/symlink.ini"
+ section: main
+ option: proxy
+ value: 'http://proxy.myorg.org:3128'
+ follow: true
+ register: result
+- name: Set the proxy key on the target directly that was changed in the previous step
+ community.general.ini_file:
+ path: "{{ remote_tmp_dir }}/my_original_file.ini"
+ section: main
+ option: proxy
+ value: 'http://proxy.myorg.org:3128'
+ register: result
+- ansible.builtin.assert:
+ that:
+ - "not (result is changed)"
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/05-ignore_spaces.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/05-ignore_spaces.yml
new file mode 100644
index 000000000..3c4b068fb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/05-ignore_spaces.yml
@@ -0,0 +1,123 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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 ignore_spaces option
+
+- name: test-ignore_spaces 1 (commented line updated) - create test file
+ copy:
+ dest: "{{ output_file }}"
+ content: "[foo]\n; bar=baz\n"
+
+- name: test-ignore_spaces 1 - set new value
+ ini_file:
+ path: "{{ output_file }}"
+ section: foo
+ option: bar
+ value: frelt
+ ignore_spaces: true
+ register: result
+
+- name: test-ignore_spaces 1 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-ignore_spaces 1 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: "[foo]\nbar = frelt\n"
+ assert:
+ that:
+ - actual_content == expected_content
+ - result is changed
+ - result.msg == 'option changed'
+
+- name: test-ignore_spaces 2 (uncommented line updated) - create test file
+ copy:
+ dest: "{{ output_file }}"
+ content: "[foo]\nbar=baz\n"
+
+- name: test-ignore_spaces 2 - set new value
+ ini_file:
+ path: "{{ output_file }}"
+ section: foo
+ option: bar
+ value: frelt
+ ignore_spaces: true
+ register: result
+
+- name: test-ignore_spaces 2 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-ignore_spaces 2 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: "[foo]\nbar = frelt\n"
+ assert:
+ that:
+ - actual_content == expected_content
+ - result is changed
+ - result.msg == 'option changed'
+
+- name: test-ignore_spaces 3 (spaces on top of no spaces) - create test file
+ copy:
+ dest: "{{ output_file }}"
+ content: "[foo]\nbar=baz\n"
+
+- name: test-ignore_spaces 3 - try to set value
+ ini_file:
+ path: "{{ output_file }}"
+ section: foo
+ option: bar
+ value: baz
+ ignore_spaces: true
+ register: result
+
+- name: test-ignore_spaces 3 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-ignore_spaces 3 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: "[foo]\nbar=baz\n"
+ assert:
+ that:
+ - actual_content == expected_content
+ - result is not changed
+ - result.msg == "OK"
+
+- name: test-ignore_spaces 4 (no spaces on top of spaces) - create test file
+ copy:
+ dest: "{{ output_file }}"
+ content: "[foo]\nbar = baz\n"
+
+- name: test-ignore_spaces 4 - try to set value
+ ini_file:
+ path: "{{ output_file }}"
+ section: foo
+ option: bar
+ value: baz
+ ignore_spaces: true
+ no_extra_spaces: true
+ register: result
+
+- name: test-ignore_spaces 4 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-ignore_spaces 4 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: "[foo]\nbar = baz\n"
+ assert:
+ that:
+ - actual_content == expected_content
+ - result is not changed
+ - result.msg == "OK"
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/06-modify_inactive_option.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/06-modify_inactive_option.yml
new file mode 100644
index 000000000..2d1d04928
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/06-modify_inactive_option.yml
@@ -0,0 +1,123 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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 modify_inactive_option option
+
+- name: test-modify_inactive_option 1 - create test file
+ copy:
+ content: |
+
+ [section1]
+ # Uncomment the line below to enable foo
+ # foo = bar
+
+ dest: "{{ output_file }}"
+
+- name: test-modify_inactive_option 1 - set value for foo with modify_inactive_option set to true
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: foo
+ value: bar
+ modify_inactive_option: true
+ register: result1
+
+- name: test-modify_inactive_option 1 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-modify_inactive_option 1 - set expected content and get current ini file content
+ set_fact:
+ expected1: |
+
+ [section1]
+ # Uncomment the line below to enable foo
+ foo = bar
+
+ content1: "{{ output_content.content | b64decode }}"
+
+- name: test-modify_inactive_option 1 - assert 'changed' is true, content is OK and option changed
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'option changed'
+ - content1 == expected1
+
+
+- name: test-modify_inactive_option 2 - create test file
+ copy:
+ content: |
+
+ [section1]
+ # Uncomment the line below to enable foo
+ # foo = bar
+
+ dest: "{{ output_file }}"
+
+- name: test-modify_inactive_option 2 - set value for foo with modify_inactive_option set to false
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: foo
+ value: bar
+ modify_inactive_option: false
+ register: result2
+
+- name: test-modify_inactive_option 2 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-modify_inactive_option 2 - set expected content and get current ini file content
+ set_fact:
+ expected2: |
+
+ [section1]
+ foo = bar
+ # Uncomment the line below to enable foo
+ # foo = bar
+
+ content2: "{{ output_content.content | b64decode }}"
+
+- name: test-modify_inactive_option 2 - assert 'changed' is true and content is OK and option added
+ assert:
+ that:
+ - result2 is changed
+ - result2.msg == 'option added'
+ - content2 == expected2
+
+
+- name: test-modify_inactive_option 3 - remove foo=bar with modify_inactive_option set to true to ensure it doesn't have effect for removal
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: foo
+ value: bar
+ modify_inactive_option: true
+ state: absent
+ register: result3
+
+- name: test-modify_inactive_option 3 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-modify_inactive_option 3 - set expected content and get current ini file content
+ set_fact:
+ expected3: |
+
+ [section1]
+ # Uncomment the line below to enable foo
+ # foo = bar
+
+ content3: "{{ output_content.content | b64decode }}"
+
+- name: test-modify_inactive_option 3 - assert 'changed' is true and content is OK and active option removed
+ assert:
+ that:
+ - result3 is changed
+ - result3.msg == 'option changed'
+ - content3 == expected3 \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/07-section_name_spaces.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/07-section_name_spaces.yml
new file mode 100644
index 000000000..6cdcfef40
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/07-section_name_spaces.yml
@@ -0,0 +1,103 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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 support for optional spaces between brackets and section names
+
+- name: Test-section_name_spaces 1 (does legacy workaround still work) - create test file
+ ansible.builtin.copy: # noqa risky-file-permissions
+ dest: "{{ output_file }}"
+ content: |
+ [ foo ]
+ ; bar=baz
+
+- name: Test-section_name_spaces 1 - update with optional spaces specified
+ community.general.ini_file: # noqa risky-file-permissions
+ path: "{{ output_file }}"
+ section: ' foo '
+ option: bar
+ value: frelt
+ register: result
+
+- name: Test-section_name_spaces 1 - read content from output file
+ ansible.builtin.slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: Test-section_name_spaces 1 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: |
+ [ foo ]
+ bar = frelt
+ ansible.builtin.assert:
+ that:
+ - actual_content == expected_content
+ - result is changed
+ - result.msg == 'option changed'
+
+
+- name: Test-section_name_spaces 2 (optional spaces omitted) - create test file
+ ansible.builtin.copy: # noqa risky-file-permissions
+ dest: "{{ output_file }}"
+ content: |
+ [ foo ]
+ bar=baz"
+
+- name: Test-section_name_spaces 2 - update without optional spaces
+ community.general.ini_file: # noqa risky-file-permissions
+ path: "{{ output_file }}"
+ section: foo
+ option: bar
+ value: frelt
+ ignore_spaces: true
+ register: result
+
+- name: Test-section_name_spaces 2 - read content from output file
+ ansible.builtin.slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: Test-section_name_spaces 2 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: "[ foo ]\nbar = frelt\n"
+ ansible.builtin.assert:
+ that:
+ - actual_content == expected_content
+ - result is changed
+ - result.msg == 'option changed'
+
+
+- name: Test-section_name_spaces 3 (legacy workaround when not required) - create test file
+ ansible.builtin.copy: # noqa risky-file-permissions
+ dest: "{{ output_file }}"
+ content: |
+ [foo]
+ ; bar=baz
+
+- name: Test-section_name_spaces 3 - update with optional spaces specified
+ community.general.ini_file: # noqa risky-file-permissions
+ path: "{{ output_file }}"
+ section: ' foo '
+ option: bar
+ value: frelt
+ register: result
+
+- name: Test-section_name_spaces 3 - read content from output file
+ ansible.builtin.slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: Test-section_name_spaces 3 - verify results
+ vars:
+ actual_content: "{{ output_content.content | b64decode }}"
+ expected_content: |
+ [foo]
+ bar = frelt
+ ansible.builtin.assert:
+ that:
+ - actual_content == expected_content
+ - result is changed
+ - result.msg == 'option changed'
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
index 918a32331..18af12f5a 100644
--- 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
@@ -7,6 +7,7 @@
set_fact:
interfaces_testfile: '{{ remote_tmp_dir }}/interfaces'
interfaces_testfile_3841: '{{ remote_tmp_dir }}/interfaces_3841'
+ interfaces_testfile_7610: '{{ remote_tmp_dir }}/interfaces_7610'
- name: Copy interfaces file
copy:
@@ -65,3 +66,60 @@
that:
- ifile_3841_a is changed
- ifile_3841_b is not changed
+
+- name: 7610 - create file
+ copy:
+ dest: '{{ interfaces_testfile_7610 }}'
+ content: |
+ iface ens3 inet dhcp
+ iface ens3 inet6 auto
+
+- name: 7610 - modify file
+ interfaces_file:
+ dest: '{{ interfaces_testfile_7610 }}'
+ iface: ens3
+ address_family: "inet6"
+ option: "{{ item.option }}"
+ value: "{{ item.value }}"
+ loop:
+ - option: "method"
+ value: "static"
+ - option: "address"
+ value: "1:2::3/48"
+
+- name: 7610 - read file
+ slurp:
+ src: '{{ interfaces_testfile_7610 }}'
+ register: content_7610
+
+- name: 7610 - check assertions
+ assert:
+ that:
+ - content_7610.content | b64decode == expected_content
+ vars:
+ expected_content: |
+ iface ens3 inet dhcp
+ iface ens3 inet6 static
+ address 1:2::3/48
+
+- name: 7610 - modify file again
+ interfaces_file:
+ dest: '{{ interfaces_testfile_7610 }}'
+ iface: ens3
+ option: method
+ value: foobar
+
+- name: 7610 - read file
+ slurp:
+ src: '{{ interfaces_testfile_7610 }}'
+ register: content_7610
+
+- name: 7610 - check assertions
+ assert:
+ that:
+ - content_7610.content | b64decode == expected_content
+ vars:
+ expected_content: |
+ iface ens3 inet foobar
+ iface ens3 inet6 foobar
+ address 1:2::3/48
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
index a74e74df4..d55007067 100644
--- 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
@@ -29,6 +29,12 @@
when:
- xtables_lock is undefined
+ - name: include tasks to test partial restore files
+ include_tasks: tests/02-partial-restore.yml
+ when:
+ - xtables_lock is undefined
+
+
- name: include tasks to test rollbacks
include_tasks: tests/10-rollback.yml
when:
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/02-partial-restore.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/02-partial-restore.yml
new file mode 100644
index 000000000..6da4814af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/02-partial-restore.yml
@@ -0,0 +1,66 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 initial rule set to use"
+ copy:
+ dest: "{{ iptables_tests }}"
+ content: |
+ *filter
+ :INPUT ACCEPT [0:0]
+ :FORWARD ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
+ COMMIT
+ *nat
+ :PREROUTING ACCEPT [151:17304]
+ :INPUT ACCEPT [151:17304]
+ :OUTPUT ACCEPT [151:17304]
+ :POSTROUTING ACCEPT [151:17304]
+ -A POSTROUTING -o eth0 -j MASQUERADE
+ COMMIT
+
+- name: "Restore initial state"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "Create partial ruleset only specifying input"
+ copy:
+ dest: "{{ iptables_tests }}"
+ content: |
+ *filter
+ :INPUT ACCEPT [0:0]
+ :FORWARD ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
+ COMMIT
+
+- name: "Check restoring partial state"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ check_mode: true
+ register: iptables_state
+
+
+- name: "assert that no changes are detected in check mode"
+ assert:
+ that:
+ - iptables_state is not changed
+
+- name: "Restore partial state"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that no changes are made"
+ assert:
+ that:
+ - iptables_state is not changed \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/aliases b/ansible_collections/community/general/tests/integration/targets/iso_create/aliases
index 4fb0bec81..73bf1b2d1 100644
--- a/ansible_collections/community/general/tests/integration/targets/iso_create/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/aliases
@@ -5,4 +5,3 @@
azp/posix/1
destructive
skip/aix
-skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases b/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases
index 54a0f1a04..394289c08 100644
--- a/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases
@@ -8,6 +8,5 @@ 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/tasks/iso_customize_exception.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml
index b2130bb6b..715f2fd38 100644
--- 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
@@ -59,7 +59,7 @@
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
+# We report error: the user should be responsible for the it
- name: "Testcase: filenames with whitespaces"
community.general.iso_customize:
src_iso: "{{ test_dir }}/test.iso"
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases b/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases
index 33041456a..5ddca1ecb 100644
--- a/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases
@@ -9,5 +9,9 @@ skip/aix
skip/osx # FIXME
skip/rhel9.0 # FIXME
skip/rhel9.1 # FIXME
+skip/rhel9.2 # FIXME
+skip/rhel9.3 # FIXME
skip/freebsd12.4 # FIXME
skip/freebsd13.2 # FIXME
+skip/freebsd13.3 # FIXME
+skip/freebsd14.0 # FIXME
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/aliases b/ansible_collections/community/general/tests/integration/targets/java_cert/aliases
index 573cb189b..0d8271ff7 100644
--- a/ansible_collections/community/general/tests/integration/targets/java_cert/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/aliases
@@ -9,3 +9,4 @@ skip/osx
skip/macos
skip/freebsd
needs/root
+skip/rhel # FIXME: keytool seems to be broken on newer RHELs
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
index 4b0a42185..b5a333b47 100644
--- 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
@@ -18,7 +18,14 @@ 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'))
+try:
+ 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'))
+except AttributeError:
+ # Python 3.12 or newer:
+ context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
+ context.load_cert_chain(certfile=os.path.join(root_dir, 'cert.pem'),
+ keyfile=os.path.join(root_dir, 'key.pem'))
+ httpd.socket = context.wrap_socket(httpd.socket)
httpd.handle_request()
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
index e135a60a3..f2898ddc2 100644
--- 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
@@ -181,7 +181,7 @@
- result_x509_changed is changed
- name: |
- We also want to make sure that the status doesnt change if we import the same cert
+ We also want to make sure that the status does not change if we import the same cert
community.general.java_cert:
cert_alias: test_cert
cert_path: "{{ test_cert2_path }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases b/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases
index 573cb189b..0d8271ff7 100644
--- a/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases
@@ -9,3 +9,4 @@ skip/osx
skip/macos
skip/freebsd
needs/root
+skip/rhel # FIXME: keytool seems to be broken on newer RHELs
diff --git a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases
index afda346c4..b85ae6419 100644
--- a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases
@@ -3,3 +3,7 @@
# 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/kernel_blacklist/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/handlers/main.yml
new file mode 100644
index 000000000..814c9c51a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/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: Remove modprobe.d
+ ansible.builtin.file:
+ path: /etc/modprobe.d
+ state: absent
+ \ No newline at end of file
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
index e169d5479..48cd38a93 100644
--- 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
@@ -36,25 +36,37 @@
path: '{{ bl_file }}'
register: stat_test_1
+- name: show bl_test_1
+ ansible.builtin.debug:
+ var: bl_test_1_depr_msgs
+ vars:
+ bl_test_1_depr_msgs: "{{ (bl_test_1.deprecations | default([])) | map(attribute='msg') }}"
+ # q('ansible.builtin.subelements', bl_test_1, 'deprecations', {'skip_missing': True}) }}"
+
- 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
+ - 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
+ # SPDX{{ '' }}-License-Identifier: GPL-3.0-or-later
blacklist aaaa
blacklist bbbb
blacklist cccc
+- name: test deprecation
+ assert:
+ that:
+ - "'deprecations' not in bl_test_1 or (ansible_version.major == 2 and ansible_version.minor == 12)"
+
- name: add new item to list
community.general.kernel_blacklist:
blacklist_file: '{{ bl_file }}'
@@ -70,13 +82,13 @@
- name: assert element is added
assert:
that:
- - bl_test_2 is changed
- - slurp_test_2.content|b64decode == content
+ - 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
+ # SPDX{{ '' }}-License-Identifier: GPL-3.0-or-later
blacklist aaaa
blacklist bbbb
@@ -95,17 +107,49 @@
src: '{{ bl_file }}'
register: slurp_test_3
-- name: assert element is added
+- name: assert element is removed
assert:
that:
- - bl_test_3 is changed
- - slurp_test_3.content|b64decode == content
+ - 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
+ # SPDX{{ '' }}-License-Identifier: GPL-3.0-or-later
blacklist aaaa
blacklist cccc
blacklist dddd
+
+############################################################################################################################################
+#
+# Issue 7362
+#
+
+- name: Create /etc/modprobe.d
+ ansible.builtin.file:
+ path: /etc/modprobe.d
+ state: directory
+ mode: '0755'
+ owner: root
+ group: root
+ notify: Remove modprobe.d
+
+- name: Create cls_rsvp file
+ ansible.builtin.copy:
+ dest: /etc/modprobe.d/cls_rsvp-blacklist.conf
+ content: |
+ blacklist cls_rsvp
+ mode: '0644'
+
+- name: Block potentially affected (and unused) modules (7362)
+ community.general.kernel_blacklist:
+ name: "{{ line_item }}"
+ state: present
+ blacklist_file: "/etc/modprobe.d/{{ line_item }}-blacklist.conf"
+ with_items:
+ - cifs
+ - cls_rsvp
+ loop_control:
+ loop_var: line_item
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
index 1941e54ef..8e052920c 100644
--- 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
@@ -20,7 +20,7 @@ docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=/auth -e KEYC
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
+its config changes) as long as it runs through completely. 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_custom_policy/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/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_custom_policy/policy/Containerfile b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile
new file mode 100644
index 000000000..3303066da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile
@@ -0,0 +1,4 @@
+FROM quay.io/keycloak/keycloak:20.0.2
+
+COPY policy.jar /opt/keycloak/providers/
+RUN /opt/keycloak/bin/kc.sh build
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json
new file mode 100644
index 000000000..9370c16cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json
@@ -0,0 +1,14 @@
+{
+ "policies": [
+ {
+ "name": "MyPolicy1",
+ "fileName": "policy-1.js",
+ "description": "My Policy 1"
+ },
+ {
+ "name": "MyPolicy2",
+ "fileName": "policy-2.js",
+ "description": "My Policy 2"
+ }
+ ]
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/keycloak_authz_custom_policy/policy/build-policy.sh b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh
new file mode 100755
index 000000000..eeca22f7e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+zip -r policy.jar META-INF/keycloak-scripts.json policy-1.js policy-2.js
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/keycloak_authz_custom_policy/policy/policy-1.js b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js
new file mode 100644
index 000000000..fa42b0719
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js
@@ -0,0 +1 @@
+$evaluation.grant();
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/keycloak_authz_custom_policy/policy/policy-2.js b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js
new file mode 100644
index 000000000..fa42b0719
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js
@@ -0,0 +1 @@
+$evaluation.grant();
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/keycloak_authz_custom_policy/readme.adoc b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc
new file mode 100644
index 000000000..cc014158f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/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 vanilla Keycloak server will not be sufficient:
+you will need to deploy a custom JAR file with two policies:
+
+* _MyPolicy1:_ policy-1.js
+* _MyPolicy2:_ policy-2.js
+
+To create a customized Keycloak test instance running on Podman first
+install the "zip" command, go to the policy subdirectory and then do
+
+[source,shell]
+----
+./build-policy.sh
+podman build --tag keycloak_authz_custom_policy_test:1.0.0 .
+podman rm mykeycloak && podman run --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password -e KC_HTTP_RELATIVE_PATH=/auth localhost/keycloak_authz_custom_policy_test:1.0.0 start-dev
+----
+
+This process probably also work with Docker just by replacing _podman_ with
+_docker_. Modify the FROM argument in Containerfile to change Keycloak version
+to test against. Quarkus versions of Keycloak should work - older versions
+will not.
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml
new file mode 100644
index 000000000..b22d75121
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml
@@ -0,0 +1,168 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 first custom policy (check_mode)
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: FirstCustomPolicy
+ state: present
+ policy_type: script-policy-1.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ check_mode: true
+ register: result
+
+- name: Assert that first custom policy was not created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "FirstCustomPolicy"
+ - result.end_state.type == "script-policy-1.js"
+ - result.msg == 'Would create custom policy FirstCustomPolicy'
+
+- name: Create first custom policy
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: FirstCustomPolicy
+ state: present
+ policy_type: script-policy-1.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: result
+
+- name: Assert that first custom policy was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "FirstCustomPolicy"
+ - result.end_state.type == "script-policy-1.js"
+ - result.msg == 'Custom policy FirstCustomPolicy created'
+
+- name: Attempt to update first custom policy (not possible)
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: FirstCustomPolicy
+ state: present
+ policy_type: script-policy-2.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: result
+
+- name: Assert that first custom policy was not modified
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "FirstCustomPolicy"
+ - result.end_state.type == "script-policy-2.js"
+ - result.msg == 'Custom policy FirstCustomPolicy already exists'
+
+# Ensure that we can create multiple instances of the custom policy
+- name: Create second instance of the custom policy
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: SecondCustomPolicy
+ state: present
+ policy_type: script-policy-1.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: result
+
+- name: Assert that second instance of the custom policy was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "SecondCustomPolicy"
+ - result.end_state.type == "script-policy-1.js"
+ - result.msg == 'Custom policy SecondCustomPolicy created'
+
+- name: Remove second instance of the custom policy (check_mode)
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: SecondCustomPolicy
+ state: absent
+ policy_type: script-policy-1.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ check_mode: true
+ register: result
+
+- name: Assert that second custom policy was not removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+ - result.msg == 'Would remove custom policy SecondCustomPolicy'
+
+- name: Remove second instance of the custom policy
+ community.general.keycloak_authz_custom_policy:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: SecondCustomPolicy
+ state: absent
+ policy_type: script-policy-1.js
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: result
+
+- name: Assert that second custom policy was removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+ - result.msg == 'Custom policy SecondCustomPolicy removed'
+
+- 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_custom_policy/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml
new file mode 100644
index 000000000..c1d5fc983
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/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_authz_permission/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/aliases
new file mode 100644
index 000000000..e1f8d6b4b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/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
+
+unsupported
+keycloak_authz_permission_info
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/readme.adoc b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/readme.adoc
new file mode 100644
index 000000000..8e052920c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/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 completely. 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_permission/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/tasks/main.yml
new file mode 100644
index 000000000..16cb6806f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/tasks/main.yml
@@ -0,0 +1,567 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 file: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:create"
+ display_name: "File create"
+ icon_uri: "http://localhost/icon.png"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Create file:delete 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: Create permission without type (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('missing required arguments') == -1
+
+- name: Create scope permission without scopes (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ permission_type: scope
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('Scopes need to defined when permission type is set to scope!') == -1
+
+- name: Create scope permission with multiple resources (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ resources:
+ - "Default Resource"
+ - "Other Resource"
+ permission_type: scope
+ scopes:
+ - "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('Only one resource can be defined for a scope permission!') == -1
+
+- name: Create scope permission with invalid policy name (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ permission_type: scope
+ scopes:
+ - "file:delete"
+ policies:
+ - "Missing Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('Unable to find authorization policy with name') == -1
+
+- name: Create scope permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ permission_type: scope
+ scopes:
+ - "file:delete"
+ policies:
+ - "Default Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that scope permission was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "ScopePermission"
+ - result.end_state.description == "Scope permission"
+ - result.end_state.type == "scope"
+ - result.end_state.resources == []
+ - result.end_state.policies|length == 1
+ - result.end_state.scopes|length == 1
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ScopePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ScopePermission"
+ - result.queried_state.description == "Scope permission"
+
+- name: Create scope permission (test for idempotency)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission"
+ permission_type: scope
+ scopes:
+ - "file:delete"
+ policies:
+ - "Default Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing changed
+ assert:
+ that:
+ - result.end_state != {}
+ - result.end_state.name == "ScopePermission"
+ - result.end_state.description == "Scope permission"
+ - result.end_state.type == "scope"
+ - result.end_state.resources == []
+ - result.end_state.policies|length == 1
+ - result.end_state.scopes|length == 1
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ScopePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ScopePermission"
+ - result.queried_state.description == "Scope permission"
+
+- name: Update scope permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission changed"
+ permission_type: scope
+ decision_strategy: 'AFFIRMATIVE'
+ scopes:
+ - "file:create"
+ - "file:delete"
+ policies: []
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that scope permission was updated correctly
+ assert:
+ that:
+ - result.changed == True
+ - result.end_state != {}
+ - result.end_state.scopes|length == 2
+ - result.end_state.policies == []
+ - result.end_state.resources == []
+ - result.end_state.name == "ScopePermission"
+ - result.end_state.description == "Scope permission changed"
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ScopePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ScopePermission"
+ - result.queried_state.description == "Scope permission changed"
+
+- name: Update scope permission (test for idempotency)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ScopePermission"
+ description: "Scope permission changed"
+ permission_type: scope
+ decision_strategy: 'AFFIRMATIVE'
+ scopes:
+ - "file:create"
+ - "file:delete"
+ policies: []
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing changed
+ assert:
+ that:
+ - result.changed == True
+ - result.end_state != {}
+ - result.end_state.scopes|length == 2
+ - result.end_state.policies == []
+ - result.end_state.resources == []
+ - result.end_state.name == "ScopePermission"
+ - result.end_state.description == "Scope permission changed"
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ScopePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ScopePermission"
+ - result.queried_state.description == "Scope permission changed"
+
+- name: Remove scope permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "ScopePermission"
+ permission_type: scope
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that scope permission was removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Remove scope permission (test for idempotency)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "ScopePermission"
+ permission_type: scope
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Create resource permission without resources (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ResourcePermission"
+ description: "Resource permission"
+ permission_type: resource
+ policies:
+ - "Default Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('A resource need to defined when permission type is set to resource!') == -1
+
+- name: Create resource permission with scopes (test for failure)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ResourcePermission"
+ description: "Resource permission"
+ permission_type: resource
+ resources:
+ - "Default Resource"
+ policies:
+ - "Default Policy"
+ scopes:
+ - "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+ failed_when: result.msg.find('Scopes cannot be defined when permission type is set to resource!') == -1
+
+- name: Create resource permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ResourcePermission"
+ description: "Resource permission"
+ resources:
+ - "Default Resource"
+ permission_type: resource
+ policies:
+ - "Default Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that resource permission was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.policies|length == 1
+ - result.end_state.resources|length == 1
+ - result.end_state.name == "ResourcePermission"
+ - result.end_state.description == "Resource permission"
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ResourcePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ResourcePermission"
+ - result.queried_state.description == "Resource permission"
+
+- name: Create resource permission (test for idempotency)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ResourcePermission"
+ description: "Resource permission"
+ resources:
+ - "Default Resource"
+ permission_type: resource
+ policies:
+ - "Default Policy"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result.end_state != {}
+ - result.end_state.policies|length == 1
+ - result.end_state.resources|length == 1
+ - result.end_state.name == "ResourcePermission"
+ - result.end_state.description == "Resource permission"
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ResourcePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ResourcePermission"
+ - result.queried_state.description == "Resource permission"
+
+- name: Update resource permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "ResourcePermission"
+ description: "Resource permission changed"
+ resources:
+ - "Default Resource"
+ permission_type: resource
+ policies: []
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that resource permission was updated correctly
+ assert:
+ that:
+ - result.changed == True
+ - result.end_state != {}
+ - result.end_state.policies == []
+ - result.end_state.resources|length == 1
+ - result.end_state.name == "ResourcePermission"
+ - result.end_state.description == "Resource permission changed"
+
+- name: Query state
+ community.general.keycloak_authz_permission_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "ResourcePermission"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that queried state matches desired end state
+ assert:
+ that:
+ - result.queried_state.name == "ResourcePermission"
+ - result.queried_state.description == "Resource permission changed"
+
+- name: Remove resource permission
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "ResourcePermission"
+ permission_type: resource
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that resource permission was removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Remove resource permission (test for idempotency)
+ community.general.keycloak_authz_permission:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "ResourcePermission"
+ permission_type: resource
+ 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_permission/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/vars/main.yml
new file mode 100644
index 000000000..c1d5fc983
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/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
index d8bcc08ec..f2b1012aa 100644
--- a/ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md
@@ -4,14 +4,16 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
SPDX-License-Identifier: GPL-3.0-or-later
-->
-The integration test can be performed as follows:
+# Running keycloak_client module integration test
-```
-# 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
+To run Keycloak client module's integration test, start a keycloak server using Docker:
-# 2. Run the integration tests:
-ansible-test integration keycloak_client --allow-unsupported -v
-```
+ docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
+
+Run the integration tests:
+
+ ansible-test integration -v keycloak_client --allow-unsupported --docker fedora35 --docker-network host
+
+Cleanup:
+
+ docker stop mykeycloak
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
deleted file mode 100644
index 5e14e9aac..000000000
--- a/ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-version: '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
index 513d5836b..5e7c7fae3 100644
--- 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
@@ -2,58 +2,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: Wait for Keycloak
+ uri:
+ url: "{{ url }}/admin/"
+ status_code: 200
+ validate_certs: no
+ register: result
+ until: result.status == 200
+ retries: 10
+ delay: 10
- name: Delete realm
- community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
- vars:
- call_args:
- id: "{{ realm }}"
- realm: "{{ realm }}"
- state: absent
+ 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: absent
- name: Create realm
- community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
- vars:
- call_args:
- id: "{{ realm }}"
- realm: "{{ realm }}"
- state: present
+ 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: 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}}'
+ 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
+ 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}}'
+ 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
+ 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) }}"
+ 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
+ redirect_uris: '{{redirect_uris1}}'
+ attributes: '{{client_attributes1}}'
+ protocol_mappers: '{{protocol_mappers1}}'
+ authorization_services_enabled: False
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)
@@ -61,3 +81,25 @@
that:
- desire_client_when_present_and_same is not changed
- check_client_when_present_and_same is not changed
+
+- name: Check client again with changed props
+ 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
+ redirect_uris: '{{redirect_uris1}}'
+ attributes: '{{client_attributes1}}'
+ protocol_mappers: '{{protocol_mappers1}}'
+ authorization_services_enabled: False
+ service_accounts_enabled: True
+ check_mode: true
+ register: check_client_when_present_and_changed
+
+- name: Assert changes detected in last tasks
+ assert:
+ that:
+ - check_client_when_present_and_changed is 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
index 53ba35fca..498f93e70 100644
--- 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
@@ -24,7 +24,7 @@ redirect_uris1:
- "http://example.b.com/"
- "http://example.a.com/"
-client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false}
+client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false, "client.secret.creation.time": 0}
protocol_mappers1:
- name: 'email'
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/README.md
new file mode 100644
index 000000000..cf4f222b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/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
+-->
+# Running keycloak_component_info module integration test
+
+To run Keycloak component info module's integration test, start a keycloak server using Docker:
+
+ docker run -d --rm --name myldap -p 389:389 minkwe/389ds:latest
+ docker run -d --rm --name mykeycloak --link myldap:ldap.example.com -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
+
+Run integration tests:
+ ansible-test integration -v keycloak_component_info --allow-unsupported --docker fedora35 --docker-network host
+
+Cleanup:
+
+ docker stop myldap mykeycloak
+
+
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_component_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/keycloak_component_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/tasks/main.yml
new file mode 100644
index 000000000..c0ca5600f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/tasks/main.yml
@@ -0,0 +1,266 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 Keycloak
+ uri:
+ url: "{{ url }}/admin/"
+ status_code: 200
+ validate_certs: no
+ register: result
+ until: result.status == 200
+ retries: 10
+ delay: 10
+
+- name: Delete realm if exists
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ state: absent
+
+- 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: Retrive ldap info when absent
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ federation }}"
+ provider_type: "org.keycloak.storage.UserStorageProvider"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert ldap is missing
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 0
+
+- 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: "ldap://ldap.example.com"
+ 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
+
+- name: Retrive ldap info
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ federation }}"
+ provider_type: "org.keycloak.storage.UserStorageProvider"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert ldap exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 1
+ - result.components[0].name == federation
+
+- name: Save ldap id
+ set_fact:
+ myLdapId: "{{ result.components[0].id }}"
+
+- name: Retrive ldap subcomponents info
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ parent_id: "{{ myLdapId }}"
+ register: result
+
+- name: Assert components exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length > 0
+
+- name: Retrive ldap subcomponents filter by name
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ parent_id: "{{ myLdapId }}"
+ name: "email"
+ register: result
+
+- name: Assert sub component with name "email" exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 1
+ - result.components[0].name == "email"
+
+- name: Retrive ldap subcomponents filter by type
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ parent_id: "{{ myLdapId }}"
+ provider_type: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
+ register: result
+
+- name: Assert ldap sub components filter by type
+ assert:
+ that:
+ - result is not changed
+ - result.components | length > 0
+ - result.components[0].providerType == "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
+
+- name: Retrive key info when absent
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ realm_key_name }}"
+ provider_type: "org.keycloak.keys.KeyProvider"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert key is missing
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 0
+
+- name: Create custom realm key
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ realm_key_name }}"
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 150
+ register: result
+
+- name: Retrive key info
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ realm_key_name }}"
+ provider_type: "org.keycloak.keys.KeyProvider"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert key exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 1
+
+- name: Retrive all realm components
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert key exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length > 0
+
+- name: Retrive all ldap in realm
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ provider_type: "org.keycloak.storage.UserStorageProvider"
+ register: result
+
+- name: Assert key exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 1
+ - result.components[0].providerType == "org.keycloak.storage.UserStorageProvider"
+ - result.components[0].name == "myldap"
+
+- name: Retrive component by name only
+ community.general.keycloak_component_info:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ realm_key_name }}"
+ register: result
+
+- name: Assert key exists
+ assert:
+ that:
+ - result is not changed
+ - result.components | length == 1
+ - result.components[0].providerType == "org.keycloak.keys.KeyProvider"
+ - result.components[0].name == realm_key_name
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/vars/main.yml
new file mode 100644
index 000000000..7f18d8459
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_component_info/vars/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
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+
+federation: myldap
+
+
+realm_key_name: testkey
+realm_private_key: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9Mi7IKXPhqGiWGwgEYEXnqc8nytG1pHbC6QYZe1gUa43jDtGYQln36It02BGw4e5XydCUj+M26X2sH+kKaV+KHEnJtcEqdAuVX1QaDVzeiOoo1/B9HC8By6NZBsOSdxpat3EvilQ+R7NP9yi53J08+vfeZSEGyPmKV1me7nJnRh3/zcRsOi92GTsBd7gApKfP8sorDjY8m9NRuPLwleK2nh/aRvj1yK8x3UAqUIbOCVaE39bSN6VUTFK2Q/+MX3vF0Zugsk7PKKmfqcEW6wj7dtSElbX4uhrfTkGMmwIWdIiLDNRA/jVRvGxUB1SyMy6kmMC8jC2QGWpZgfkSKtHlAgMBAAECggEACWkSVh7ntmjtwM+Z47vVJkt2NBS8vxPt206DYOeXbzaVUV6mkrP0LSZKL3bi1GE8fW3am9UXWF8fQt04dm3c1G4JRojtkXrBq72Y3Y3eGWyGdx8chWCOPwDdwFsbhbC6ZRo8PUDcZVekJd1Vj38XbBXQl+WAUcnTzauAF+1kz9mhJq1gpglIbB+8l7VjMXwXeaGWJQ5OL/MSsq7r3P1elVjHwprFBM7HHA5+RTu/KY/GcEutgm5uwTRqRZNC1IBXAQtBO7HQJbuLqDPTQ3RRCPEur8R+0dk5bF+8IyzQ8Bh+Dhuou9xzfS/A7lV6L/CZSpv4Bvq1H3Uxk+orXf2Q2QKBgQDBOf1nSJB0VgQdIcdtgVpVgQ2SyWAd+N8Qk7QsyVQf9f7ZqiFLejWJbaaeY9WtfZ01D8tgHJfPqsO1/Jux255mtkyk2K2c6dav1Lsd4l+iPfidsDJNWkcd59nQqwC9BLjzWK/J4rO20apm34abLaZ9oVk8Mgz8VWJWOxTgCr+COQKBgQD6qP1lm6rzlCSIEz9eCuGPkQkVo+NIP437e3i+sxtkLlMgnmfzSwSJdVF8AKH3gXi3NyWjfBVYeAZEkm1kHF8IWOiK4U1y95Vx3uud3NX4SC+cjePc+pDPQJiz9L+zq9I6WFZWmm7n/9heTxu/l0vxI4FHaBmt95BMwLJNkzbdDQKBgCHGwUUMqjOr1YxCG1pJAkFwDa9bBDI5DsUXDKfHia0Mkz/5PVi0RCeBw15slS1+h7x+xk5GsULb1to5Df5JJadOtpcaST7koWKbDRpsN8tkidEGu8RJw6S2opyXR8nCyZHALvpbZo7Ol7rj1+PIVxIe4jpjhWGWi1oHed6wAkoBAoGAJx2F5XxEUhx1EvMF+XPzPQciBsl7Z0PbsTnUXtXuWVTNThLKH/I99AFlxNcIb2o530VwzzFG13Zra/n5rhyrS88sArgj8OPn40wpMopKraL+Iw0VWN+VB3KKIdL4s14FwWsVlhAlbHjFV/o6V0yR4kBrJSx+jWJLl16etHJbpmUCgYBUWCQwcT1aw9XHWJXiNYTnQSYg88hgGYhts1qSzhfu+n1t2BlAlxM0gu2+gez21mM8uiYsqbU2OZeG2U4as6kdai8Q4tzNQt2f1r3ZewJN/QHrkx6FT94PNa0w4ILiQ9Eu7xssaHcYjHyrI1NlbMKypVy6waDG2ajLOFAVeHGpOg==
+ -----END PRIVATE KEY-----
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
index 1941e54ef..8e052920c 100644
--- a/ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc
@@ -20,7 +20,7 @@ docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=/auth -e KEYC
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
+its config changes) as long as it runs through completely. 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_rolemapping/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/README.md
new file mode 100644
index 000000000..db58acb7b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/README.md
@@ -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
+-->
+
+# `keycloak_group_rolemapping` Integration Tests
+
+## Test Server
+
+Prepare a development server, tested with Keycloak versions tagged 22.0 and 23.0:
+
+```sh
+docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password --rm quay.io/keycloak/keycloak:22.0 start-dev
+```
+
+## Run Tests
+
+```sh
+ansible localhost --module-name include_role --args name=keycloak_group_rolemapping
+```
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/aliases
new file mode 100644
index 000000000..9e2cd0dc4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/aliases
@@ -0,0 +1,4 @@
+# Copyright (c) 2023, Alexander Groß (@agross)
+# 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_group_rolemapping/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/tasks/main.yml
new file mode 100644
index 000000000..f1e6371e2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/tasks/main.yml
@@ -0,0 +1,160 @@
+# Copyright (c) 2023, Alexander Groß (@agross)
+# 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 realm roles
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ name: "{{ item }}"
+ state: present
+ loop:
+ - "{{ role_1 }}"
+ - "{{ role_2 }}"
+
+- name: Create group
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ name: "{{ group }}"
+ state: present
+
+- name: Map realm roles to group
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_1 }}"
+ - name: "{{ role_2 }}"
+ state: present
+ register: result
+
+- name: Assert realm roles are assigned to group
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - result.end_state | count == 2
+
+- name: Map realm roles to group again (idempotency)
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_1 }}"
+ - name: "{{ role_2 }}"
+ state: present
+ register: result
+
+- name: Assert realm roles stay assigned to group
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Unmap realm role 1 from group
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_1 }}"
+ state: absent
+ register: result
+
+- name: Assert realm role 1 is unassigned from group
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - result.end_state | count == 1
+ - result.end_state[0] == role_2
+
+- name: Unmap realm role 1 from group again (idempotency)
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_1 }}"
+ state: absent
+ register: result
+
+- name: Assert realm role 1 stays unassigned from group
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Unmap realm role 2 from group
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_2 }}"
+ state: absent
+ register: result
+
+- name: Assert no realm roles are assigned to group
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - result.end_state | count == 0
+
+- name: Unmap realm role 2 from group again (idempotency)
+ community.general.keycloak_realm_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+ realm: "{{ realm }}"
+ group_name: "{{ group }}"
+ roles:
+ - name: "{{ role_2 }}"
+ state: absent
+ register: result
+
+- name: Assert no realm roles are assigned to group
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+ - result.end_state | count == 0
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/vars/main.yml
new file mode 100644
index 000000000..0848499e7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/vars/main.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) 2023, Alexander Groß (@agross)
+# 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
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+
+role_1: myrole-1
+role_2: myrole-2
+
+group: mygroup
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
index 79ba33049..afad9740e 100644
--- 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
@@ -35,14 +35,14 @@
syncMode: FORCE
mappers:
- name: "first_name"
- identityProviderAlias: "oidc-idp"
+ identityProviderAlias: "{{ idp }}"
identityProviderMapper: "oidc-user-attribute-idp-mapper"
config:
claim: "first_name"
user.attribute: "first_name"
syncMode: "INHERIT"
- name: "last_name"
- identityProviderAlias: "oidc-idp"
+ identityProviderAlias: "{{ idp }}"
identityProviderMapper: "oidc-user-attribute-idp-mapper"
config:
claim: "last_name"
@@ -84,14 +84,14 @@
syncMode: FORCE
mappers:
- name: "first_name"
- identityProviderAlias: "oidc-idp"
+ identityProviderAlias: "{{ idp }}"
identityProviderMapper: "oidc-user-attribute-idp-mapper"
config:
claim: "first_name"
user.attribute: "first_name"
syncMode: "INHERIT"
- name: "last_name"
- identityProviderAlias: "oidc-idp"
+ identityProviderAlias: "{{ idp }}"
identityProviderMapper: "oidc-user-attribute-idp-mapper"
config:
claim: "last_name"
@@ -109,7 +109,7 @@
that:
- result is not changed
-- name: Update existing identity provider (with change)
+- name: Update existing identity provider (with change, no mapper change)
community.general.keycloak_identity_provider:
auth_keycloak_url: "{{ url }}"
auth_realm: "{{ admin_realm }}"
@@ -132,6 +132,109 @@
- result.existing.enabled == true
- result.end_state.enabled == false
+- name: Update existing identity provider (delete mapper)
+ 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: present
+ mappers:
+ - name: "first_name"
+ identityProviderAlias: "{{ idp }}"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "first_name"
+ user.attribute: "first_name"
+ syncMode: "INHERIT"
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider updated
+ assert:
+ that:
+ - result is changed
+ - result.existing.mappers | length == 2
+ - result.end_state.mappers | length == 1
+ - result.end_state.mappers[0].name == "first_name"
+
+- name: Update existing identity provider (add mapper)
+ 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: present
+ mappers:
+ - name: "last_name"
+ identityProviderAlias: "{{ idp }}"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "last_name"
+ user.attribute: "last_name"
+ syncMode: "INHERIT"
+ - name: "first_name"
+ identityProviderAlias: "{{ idp }}"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "first_name"
+ user.attribute: "first_name"
+ syncMode: "INHERIT"
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider updated
+ assert:
+ that:
+ - result is changed
+ - result.existing.mappers | length == 1
+ - result.end_state.mappers | length == 2
+
+- name: Update existing identity provider (no change, test mapper idempotency)
+ 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: present
+ mappers:
+ - name: "last_name"
+ identityProviderAlias: "{{ idp }}"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "last_name"
+ user.attribute: "last_name"
+ syncMode: "INHERIT"
+ - name: "first_name"
+ identityProviderAlias: "{{ idp }}"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "first_name"
+ user.attribute: "first_name"
+ syncMode: "INHERIT"
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider updated
+ assert:
+ that:
+ - result is not changed
+
- name: Delete existing identity provider
community.general.keycloak_identity_provider:
auth_keycloak_url: "{{ url }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/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_realm_key/readme.adoc b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/readme.adoc
new file mode 100644
index 000000000..8e052920c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/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 completely. 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_realm_key/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/tasks/main.yml
new file mode 100644
index 000000000..c02950600
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/tasks/main.yml
@@ -0,0 +1,373 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 test realm to avoid failures from previous failed runs
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ realm }}"
+ state: absent
+
+- name: Create Keycloak test realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ realm }}"
+ state: present
+
+- name: Create custom realm key (check mode)
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 150
+ check_mode: true
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["150"]
+ - result.msg == "Realm key testkey would be created"
+
+- name: Create custom realm key
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 150
+ diff: true
+ register: result
+
+- name: Assert that realm key was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["150"]
+ - result.msg == "Realm key testkey created"
+
+- name: Create custom realm key (test for idempotency)
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 150
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["150"]
+ - result.msg == "Realm key testkey was in sync"
+
+- name: Update custom realm key (check mode)
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 140
+ check_mode: true
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["140"]
+ - result.msg == "Realm key testkey would be changed: config.priority ['150'] -> ['140']"
+
+- name: Update custom realm key
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 140
+ diff: true
+ register: result
+
+- name: Assert that realm key was updated
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["140"]
+ - result.msg == "Realm key testkey changed: config.priority ['150'] -> ['140']"
+
+- name: Update custom realm key (test for idempotency)
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 140
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["140"]
+ - result.msg == "Realm key testkey was in sync"
+
+- name: Force update custom realm key
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ force: true
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key_2 }}"
+ certificate: ""
+ enabled: true
+ active: true
+ priority: 140
+ register: result
+
+- name: Assert that forced update ran correctly
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["140"]
+ - result.msg == "Realm key testkey was forcibly updated"
+
+- name: Remove custom realm key
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: absent
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ priority: 140
+ diff: true
+ register: result
+
+- name: Assert that realm key was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+ - result.msg == "Realm key testkey deleted"
+
+- name: Remove custom realm key (test for idempotency)
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey
+ state: absent
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: ""
+ priority: 140
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+ - result.msg == "Realm key testkey not present"
+
+- name: Create custom realm key with a custom certificate
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey_with_certificate
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "{{ realm_private_key }}"
+ certificate: "{{ realm_certificate }}"
+ enabled: true
+ active: true
+ priority: 150
+ diff: true
+ register: result
+
+- name: Assert that realm key with custom certificate was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey_with_certificate"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["150"]
+ - result.msg == "Realm key testkey_with_certificate created"
+
+- name: Attempt to change the private key and the certificate
+ community.general.keycloak_realm_key:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: testkey_with_certificate
+ state: present
+ parent_id: "{{ realm }}"
+ config:
+ private_key: "a different private key string"
+ certificate: "a different certificate string"
+ enabled: true
+ active: true
+ priority: 150
+ diff: true
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "testkey_with_certificate"
+ - result.end_state.parentId == "realm_key_test"
+ - result.end_state.providerId == "rsa"
+ - result.end_state.providerType == "org.keycloak.keys.KeyProvider"
+ - result.end_state.config.active == ["true"]
+ - result.end_state.config.enabled == ["true"]
+ - result.end_state.config.algorithm == ["RS256"]
+ - result.end_state.config.priority == ["150"]
+ - result.msg == "Realm key testkey_with_certificate was in sync"
+
+- name: Remove Keycloak test realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ realm }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/vars/main.yml
new file mode 100644
index 000000000..d39cf8f73
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/vars/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
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: realm_key_test
+realm_private_key_name: testkey
+realm_private_key: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9Mi7IKXPhqGiWGwgEYEXnqc8nytG1pHbC6QYZe1gUa43jDtGYQln36It02BGw4e5XydCUj+M26X2sH+kKaV+KHEnJtcEqdAuVX1QaDVzeiOoo1/B9HC8By6NZBsOSdxpat3EvilQ+R7NP9yi53J08+vfeZSEGyPmKV1me7nJnRh3/zcRsOi92GTsBd7gApKfP8sorDjY8m9NRuPLwleK2nh/aRvj1yK8x3UAqUIbOCVaE39bSN6VUTFK2Q/+MX3vF0Zugsk7PKKmfqcEW6wj7dtSElbX4uhrfTkGMmwIWdIiLDNRA/jVRvGxUB1SyMy6kmMC8jC2QGWpZgfkSKtHlAgMBAAECggEACWkSVh7ntmjtwM+Z47vVJkt2NBS8vxPt206DYOeXbzaVUV6mkrP0LSZKL3bi1GE8fW3am9UXWF8fQt04dm3c1G4JRojtkXrBq72Y3Y3eGWyGdx8chWCOPwDdwFsbhbC6ZRo8PUDcZVekJd1Vj38XbBXQl+WAUcnTzauAF+1kz9mhJq1gpglIbB+8l7VjMXwXeaGWJQ5OL/MSsq7r3P1elVjHwprFBM7HHA5+RTu/KY/GcEutgm5uwTRqRZNC1IBXAQtBO7HQJbuLqDPTQ3RRCPEur8R+0dk5bF+8IyzQ8Bh+Dhuou9xzfS/A7lV6L/CZSpv4Bvq1H3Uxk+orXf2Q2QKBgQDBOf1nSJB0VgQdIcdtgVpVgQ2SyWAd+N8Qk7QsyVQf9f7ZqiFLejWJbaaeY9WtfZ01D8tgHJfPqsO1/Jux255mtkyk2K2c6dav1Lsd4l+iPfidsDJNWkcd59nQqwC9BLjzWK/J4rO20apm34abLaZ9oVk8Mgz8VWJWOxTgCr+COQKBgQD6qP1lm6rzlCSIEz9eCuGPkQkVo+NIP437e3i+sxtkLlMgnmfzSwSJdVF8AKH3gXi3NyWjfBVYeAZEkm1kHF8IWOiK4U1y95Vx3uud3NX4SC+cjePc+pDPQJiz9L+zq9I6WFZWmm7n/9heTxu/l0vxI4FHaBmt95BMwLJNkzbdDQKBgCHGwUUMqjOr1YxCG1pJAkFwDa9bBDI5DsUXDKfHia0Mkz/5PVi0RCeBw15slS1+h7x+xk5GsULb1to5Df5JJadOtpcaST7koWKbDRpsN8tkidEGu8RJw6S2opyXR8nCyZHALvpbZo7Ol7rj1+PIVxIe4jpjhWGWi1oHed6wAkoBAoGAJx2F5XxEUhx1EvMF+XPzPQciBsl7Z0PbsTnUXtXuWVTNThLKH/I99AFlxNcIb2o530VwzzFG13Zra/n5rhyrS88sArgj8OPn40wpMopKraL+Iw0VWN+VB3KKIdL4s14FwWsVlhAlbHjFV/o6V0yR4kBrJSx+jWJLl16etHJbpmUCgYBUWCQwcT1aw9XHWJXiNYTnQSYg88hgGYhts1qSzhfu+n1t2BlAlxM0gu2+gez21mM8uiYsqbU2OZeG2U4as6kdai8Q4tzNQt2f1r3ZewJN/QHrkx6FT94PNa0w4ILiQ9Eu7xssaHcYjHyrI1NlbMKypVy6waDG2ajLOFAVeHGpOg==
+ -----END PRIVATE KEY-----
+realm_certificate: |
+ -----BEGIN CERTIFICATE-----
+ MIIDQDCCAiigAwIBAgIUMfPlHWcZn6xfeSjfbhgmt4yy6mMwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMzA4MTgxMTU5MDFaFw0zMzA4MTUxMTU5MDFaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Mi7IKXPhqGiWGwgEYEXnqc8nytG1pHbC6QYZe1gUa43jDtGYQln36It02BGw4e5XydCUj+M26X2sH+kKaV+KHEnJtcEqdAuVX1QaDVzeiOoo1/B9HC8By6NZBsOSdxpat3EvilQ+R7NP9yi53J08+vfeZSEGyPmKV1me7nJnRh3/zcRsOi92GTsBd7gApKfP8sorDjY8m9NRuPLwleK2nh/aRvj1yK8x3UAqUIbOCVaE39bSN6VUTFK2Q/+MX3vF0Zugsk7PKKmfqcEW6wj7dtSElbX4uhrfTkGMmwIWdIiLDNRA/jVRvGxUB1SyMy6kmMC8jC2QGWpZgfkSKtHlAgMBAAGjLjAsMAsGA1UdDwQEAwIEkDAdBgNVHQ4EFgQUcZirWRV5EzRhanUVSQ9rmAavVbEwDQYJKoZIhvcNAQELBQADggEBAIt2aFr/sxvtZfDc+Nb9tgspBuoX8f9Gf9mrS6dTdvdqSMHQrcoejSEEAZNljdSpKAhnhyR3+uCIev++WS4tixZoooQ8aYxDGNIwyry51GNEK7LKXVRmkbZFODidRuYZ1XWQORaJoaXWplaPaNtLvUr1swachz36K4n8/UIi109w/addajOHFbFGAzUmGRR4saMZPGrQCaNFje7G1o5wb/mQD1L+Jfk81Id5/F6NFBsSEIi+/O7Xs7fOWuab6cdfwI7zQQclEo55WQkLXefFLn+Ju0Ftgl023awpNEE4pjl6jD5VSEOkQ+I2sxGvymgjz7Av4zPOD/Lr05lRnMxf8dA=
+ -----END CERTIFICATE-----
+realm_private_key_2: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCyQ5FKuqbnWEtt
+ KI0FHKFvd+G/RyEI2ow29Ytjs3fZ7/gMYfXozHLLJl3jgCOvSf9Ta55arL0XnCCf
+ RKQb0vpgMmOTQw++A1UmNXe8atTczZMRiHMHFdLhXUvUKthcMGOrTH8xegCnm0bG
+ rZwimjQDog/kROMAN78Uv8SD1lMpGBxPr2DWXNl4kRF670m/jC0cM7SeDGCCKVF5
+ SEh6rMDgI62AxKnbtxuAbF9SOO/6kTsYv5+dc8wxDEb0aaT1jC1CLhjAVmjc6vO7
+ WHE0LLas+ARs4ghMONLN6VdOkJxBuEtlLqM3M+/viD1TRftZCeLarYLWdEsg8Yz9
+ Ufb0oawzAgMBAAECggEARqPDxWsljHNOoFj7WNU5m6RTzqpvCsUf3v96Vu3dRn1z
+ O+Ttv2yU6K+xcN9sRJ/8D6CLxb7Bx8NUoghfR69ZDBmrn8VpTZCgg12Yrw9efojw
+ CHibrGkXgbqou9CmoBGEzXKozIBeFgzQBRby0jts9SuZRImPspxkmeJMCzo5BgUg
+ ksNibaWikvUJYMgFc7PdXEvxhCKcWTTGC3fxJwpRxXkqKsYDa3JhdhloH8hHqynm
+ o7WEXeGAn4UV7C1tg3OdTciHn/ONMRItPcyonwk19meZTvsEub6ZsNjVg/5oJVBr
+ WG8vPZBi1VzAMayDXxDOnEAKW5eJXRSNX1vZ7EQTEQKBgQDXg5pSp9hVdVZc+eN/
+ Ab/1NMMdgrQdbyTeB9esjLiwNuXysQm/KaG8gTkLpiKVvJ8R7SOcxb9Y5Gt9Y5Ej
+ eu943V4zLDIzNt/ST4bXGW/gQ84zkMBdhKz9hKA5tartVjI1ycznjpDbgn/jAYPI
+ 8VXGmjID2oDIJ7P+dLD8lMBDvQKBgQDTwIyimy+4EwFUuuppfWArXRsqsWUScGWD
+ +06xbc+Ld92LJBvakvSTdDNnS/PlYGl/fJjqQ4wq5UPREJYCi3UW9I5jtfsIg8Pl
+ oCnIhEYkn8xPZ7X8grU4emkM6QAPhstCDlXE6t0T202TpYVYjtEEDRQu4rKAbJ0h
+ gqSh5Ge2rwKBgEjrx6jWEBYCaOF20ComTmxKmQaANi+Lbt8NqkVBLDC7spymmJSt
+ IoOk+cdeRG+D7hLjuVwPcQpD57b6nJ5zt1mfFYOdHbNEiwEfVZGskrVAXCIIhX5f
+ KSVy3cAJHzfFJaIbkRB8pbkQc/M8jPnN5ucXP3scUNzoyjd8BnLAZjnFAoGAWwwY
+ rDYTz48EbH0uG4uYFS0kaDf8YHBJhfVBgdLYgXxZmuE8xL+ZP+mfzJOA3CiXVASr
+ 71Z551vKzBLYnWF/SA6BRuhRdvjI+2vha2FMk6TOAXpzao59AzrG/pEUwJhRvyZQ
+ xKnDwyzxb0GlU02dG6PQANTisYuCCI2W4jFGUusCgYB72p5o5uBr7qrFMTdMMxxe
+ f/9Go/9QBR/uNYk3D/rWj0F/bXGbiYMddNMD4v3XE24NL4ZvBJn0Po64Tuz5+wtu
+ 5ICKc6ED1l55MPsKdegVMpXGIFRjZt2TtCk4FE68m5QJpT1IIK7I9jv0+FGKjFYa
+ ukdTEghu13cANd8eKpxBsQ==
+ -----END PRIVATE KEY-----
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_role/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_role/README.md
new file mode 100644
index 000000000..ccb4c8ffa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_role/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
+-->
+# Running keycloak_user module integration test
+
+To run Keycloak user module's integration test, start a keycloak server using Docker or Podman:
+
+ podman|docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
+
+Source Ansible env-setup from ansible github repository
+
+Run integration tests:
+
+ ansible-test integration keycloak_role --python 3.10 --allow-unsupported
+
+Cleanup:
+
+ podman|docker stop mykeycloak
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
index 61b62629a..c649b8680 100644
--- 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
@@ -248,3 +248,236 @@
that:
- result is not changed
- result.end_state == {}
+
+- name: Create realm role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role is created with composites
+ assert:
+ that:
+ - result is changed
+ - result.end_state.composites | length == 3
+
+- name: Change realm role with composites no change
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role with composites have not changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state.composites | length == 3
+
+- name: Remove composite from realm role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites_with_absent }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert composite was removed from realm role with composites
+ assert:
+ that:
+ - result is changed
+ - result.end_state.composites | length == 2
+
+- name: Delete realm role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ keycloak_role_name }}"
+ 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 with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ keycloak_role_name }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert not changed and realm role absent
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Create client role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role is created with composites
+ assert:
+ that:
+ - result is changed
+ - result.end_state.composites | length == 3
+
+- name: Change client role with composites no change
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role with composites have not changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state.composites | length == 3
+
+- name: Remove composite from client role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ keycloak_role_name }}"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ description: "{{ keycloak_role_description }}"
+ composite: "{{ keycloak_role_composite }}"
+ composites: "{{ keycloak_role_composites_with_absent }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert composite was removed from client role with composites
+ assert:
+ that:
+ - result is changed
+ - result.end_state.composites | length == 2
+
+- name: Delete client role with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ keycloak_role_name }}"
+ client_id: "{{ client_id }}"
+ 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 with composites
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ keycloak_role_name }}"
+ client_id: "{{ client_id }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert not changed and client role absent
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {} \ No newline at end of file
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
index b003311e0..0af55dfc5 100644
--- 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
@@ -12,3 +12,30 @@ client_id: myclient
role: myrole
description_1: desc 1
description_2: desc 2
+
+keycloak_role_name: test
+keycloak_role_description: test
+keycloak_role_composite: true
+keycloak_role_composites:
+ - name: view-clients
+ client_id: "realm-management"
+ state: present
+ - name: query-clients
+ client_id: "realm-management"
+ state: present
+ - name: offline_access
+ state: present
+keycloak_client_id: test-client
+keycloak_client_name: test-client
+keycloak_client_description: This is a client for testing purpose
+role_state: present
+
+keycloak_role_composites_with_absent:
+ - name: view-clients
+ client_id: "realm-management"
+ state: present
+ - name: query-clients
+ client_id: "realm-management"
+ state: present
+ - name: offline_access
+ state: absent \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_user/README.md
new file mode 100644
index 000000000..07ecc3f83
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user/README.md
@@ -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
+-->
+# Running keycloak_user module integration test
+
+To run Keycloak user module's integration test, start a keycloak server using Docker or Podman:
+
+ podman|docker run -d --rm --name mykeycloak -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:latest start-dev --http-relative-path /auth
+
+Source Ansible env-setup from ansible github repository
+
+Run integration tests:
+
+ ansible-test integration keycloak_user --python 3.10 --allow-unsupported
+
+Cleanup:
+
+ podman|docker stop mykeycloak
+
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_user/aliases
new file mode 100644
index 000000000..0abc6a467
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user/aliases
@@ -0,0 +1,4 @@
+# Copyright (c) 2023, INSPQ Philippe Gauthier (@elfelip)
+# 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/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user/tasks/main.yml
new file mode 100644
index 000000000..0f1fe152d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user/tasks/main.yml
@@ -0,0 +1,114 @@
+# 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 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: 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 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: "{{ keycloak_client_role }}"
+ description: "{{ description_1 }}"
+ state: present
+
+- name: Create new groups
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ item.name }}"
+ state: present
+ with_items: "{{ keycloak_user_groups }}"
+
+- name: Create user
+ community.general.keycloak_user:
+ auth_keycloak_url: "{{ url }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ auth_realm: "{{ admin_realm }}"
+ username: "{{ keycloak_username }}"
+ realm: "{{ realm }}"
+ first_name: Ceciestes
+ last_name: Untestes
+ email: ceciestuntestes@test.com
+ groups: "{{ keycloak_user_groups }}"
+ attributes: "{{ keycloak_user_attributes }}"
+ state: present
+ register: create_result
+
+- name: debug
+ debug:
+ var: create_result
+
+- name: Assert user is created
+ assert:
+ that:
+ - create_result.changed
+ - create_result.end_state.username == 'test'
+ - create_result.end_state.attributes | length == 3
+ - create_result.end_state.groups | length == 2
+
+- name: Delete User
+ community.general.keycloak_user:
+ auth_keycloak_url: "{{ url }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ auth_realm: "{{ admin_realm }}"
+ username: "{{ keycloak_username }}"
+ realm: "{{ realm }}"
+ first_name: Ceciestes
+ last_name: Untestes
+ email: ceciestuntestes@test.com
+ groups: "{{ keycloak_user_groups }}"
+ attributes: "{{ keycloak_user_attributes }}"
+ state: absent
+ register: delete_result
+
+- name: debug
+ debug:
+ var: delete_result
+
+- name: Assert user is deleted
+ assert:
+ that:
+ - delete_result.changed
+ - delete_result.end_state | length == 0
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user/vars/main.yml
new file mode 100644
index 000000000..9962aba54
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user/vars/main.yml
@@ -0,0 +1,46 @@
+---
+# 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
+
+keycloak_username: test
+keycloak_service_account_client_id: "{{ client_id }}"
+keycloak_user_realm_roles:
+ - name: offline_access
+ - name: "{{ role }}"
+keycloak_client_role: test
+keycloak_user_client_roles:
+ - client_id: "{{ client_id }}"
+ roles:
+ - name: "{{ keycloak_client_role }}"
+ - client_id: "{{ realm }}-realm"
+ roles:
+ - name: view-users
+ - name: query-users
+keycloak_user_attributes:
+ - name: attr1
+ values:
+ - value1s
+ state: present
+ - name: attr2
+ values:
+ - value2s
+ state: present
+ - name: attr3
+ values:
+ - value3s
+ state: present
+keycloak_user_groups:
+ - name: test
+ state: present
+ - name: test2
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/auth.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/auth.yml
new file mode 100644
index 000000000..a8c7a13ee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/auth.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
+
+- debug:
+ msg: Running tests/auth.yml
+
+####################################################################
+## Search ##########################################################
+####################################################################
+- name: Test simple search for password authenticated user
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ scope: "onelevel"
+ filter: "(uid=ldaptest)"
+ bind_dn: "uid=ldaptest,ou=users,dc=example,dc=com"
+ bind_pw: "test1pass!"
+ ignore_errors: true
+ register: output
+
+- name: assert that test LDAP user can read its password
+ assert:
+ that:
+ - output is not failed
+ - output.results | length == 1
+ - output.results.0.userPassword is defined
+
+- name: Test simple search for cert authenticated user
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ server_uri: "ldap://localhost/"
+ start_tls: true
+ ca_path: /usr/local/share/ca-certificates/ca.crt
+ scope: "onelevel"
+ filter: "(uid=ldaptest)"
+ client_cert: "/root/user.crt"
+ client_key: "/root/user.key"
+ ignore_errors: true
+ register: output
+
+- name: assert that test LDAP user can read its password
+ assert:
+ that:
+ - output is not failed
+ - output.results | length == 1
+ - output.results.0.userPassword is defined
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
index 36d245d39..11e5d6562 100644
--- 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
@@ -23,3 +23,17 @@
- output is not failed
- output.results | length == 1
- output.results.0.displayName == "LDAP Test"
+
+- name: Test simple search for a user with no results
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ scope: "onelevel"
+ filter: "(uid=nonexistent)"
+ ignore_errors: true
+ register: output
+
+- name: assert that the output is empty
+ assert:
+ that:
+ - output is not failed
+ - output.results | length == 0
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/pages.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/pages.yml
new file mode 100644
index 000000000..32575854b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/pages.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
+
+- debug:
+ msg: Running tests/pages.yml
+
+####################################################################
+## Search ##########################################################
+####################################################################
+- name: Test paged search for all users
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ scope: "onelevel"
+ page_size: 1
+ ignore_errors: true
+ register: output
+
+- name: assert that the right number of results are returned
+ assert:
+ that:
+ - output is not failed
+ - output.results | length == 2
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/schema.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/schema.yml
new file mode 100644
index 000000000..892eac3cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/schema.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/schema.yml
+
+####################################################################
+## Search ##########################################################
+####################################################################
+- name: Test for ldap schema output
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ scope: "onelevel"
+ schema: true
+ ignore_errors: true
+ register: output
+
+- name: Assert that the schema output is correct
+ assert:
+ that:
+ - output is not failed
+ - output.results | length >= 1
+ - "{{ 'displayName' in output.results.0.attrs }}"
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
index 70649f505..0e583e7a1 100644
--- 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
@@ -13,7 +13,7 @@
ansible.builtin.package:
name:
- net-tools
- - netcat
+ - netcat-openbsd
state: latest
when: ansible_os_family == "Debian"
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases b/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases
index f7f4063f6..a5d3e27f9 100644
--- a/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases
@@ -6,3 +6,5 @@ azp/posix/3
destructive
needs/root
skip/aix
+skip/freebsd
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/basic.yml b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/basic.yml
new file mode 100644
index 000000000..8718e0be8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/basic.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
+
+- name: Is the locale we're going to test against installed? {{ locale_basic.localegen }}
+ command: locale -a
+ register: initial_state
+ ignore_errors: true
+
+- name: Make sure the locale is not installed {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: absent
+
+- name: Is the locale present? {{ locale_basic.localegen }}
+ command: locale -a
+ register: cleaned
+ ignore_errors: true
+
+- name: Make sure the locale is not present {{ locale_basic.localegen }}
+ assert:
+ that:
+ - locale_basic.skip_removal or locale_basic.locales | intersect(cleaned.stdout_lines) == []
+
+- name: Install the locale {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: present
+ register: output_present
+
+- name: Is the locale present? {{ locale_basic.localegen }}
+ command: locale -a
+ register: post_check_output_present
+ ignore_errors: true
+
+- name: Make sure the locale is present and we say we installed it {{ locale_basic.localegen }}
+ assert:
+ that:
+ - locale_basic.locales | intersect(post_check_output_present.stdout_lines) != []
+ - locale_basic.skip_removal or output_present is changed
+
+- name: Install the locale a second time {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: present
+ register: output_present_idempotent
+
+- name: Is the locale present? {{ locale_basic.localegen }}
+ command: locale -a
+ register: post_check_output_present_idempotent
+ ignore_errors: true
+
+- name: Make sure the locale is present and we reported no change {{ locale_basic.localegen }}
+ assert:
+ that:
+ - locale_basic.locales | intersect(post_check_output_present_idempotent.stdout_lines) != []
+ - output_present_idempotent is not changed
+
+- name: Removals
+ when: locale_basic.skip_removal is false
+ block:
+ - name: Remove the locale {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: absent
+ register: output_absent
+
+ - name: Is the locale present? {{ locale_basic.localegen }}
+ command: locale -a
+ register: post_check_output_absent
+ ignore_errors: true
+
+ - name: Make sure the locale is absent and we reported a change {{ locale_basic.localegen }}
+ assert:
+ that:
+ - locale_basic.locales | intersect(post_check_output_absent.stdout_lines) == []
+ - output_absent is changed
+
+ - name: Remove the locale a second time {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: absent
+ register: output_absent_idempotent
+
+ - name: Is the locale present? {{ locale_basic.localegen }}
+ command: locale -a
+ register: post_check_output_absent_idempotent
+ ignore_errors: true
+
+ - name: Make sure the locale is absent and we reported no change {{ locale_basic.localegen }}
+ assert:
+ that:
+ - locale_basic.locales | intersect(post_check_output_absent_idempotent.stdout_lines) == []
+ - output_absent_idempotent is not changed
+
+# Cleanup
+- name: Reinstall the locale we tested against if it was initially installed {{ locale_basic.localegen }}
+ locale_gen:
+ name: "{{ locale_basic.localegen }}"
+ state: present
+ when: locale_basic.locales | intersect(initial_state.stdout_lines) != []
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
deleted file mode 100644
index c6bdcc046..000000000
--- a/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml
+++ /dev/null
@@ -1,99 +0,0 @@
----
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-- name: 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
index de3e673be..2d9dfcee0 100644
--- 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
@@ -8,5 +8,11 @@
# GNU General Public License v3.0+ (see LICENSES/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')
+- name: Bail out if not supported
+ ansible.builtin.meta: end_play
+ when: ansible_distribution not in ('Ubuntu', 'Debian')
+
+- include_tasks: basic.yml
+ loop: "{{ locale_list_basic }}"
+ loop_control:
+ loop_var: locale_basic
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/locale_gen/vars/main.yml
new file mode 100644
index 000000000..44327ddd3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/vars/main.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
+
+# locale_basic: pt_BR
+
+locale_list_basic:
+ - localegen: pt_BR
+ locales: [pt_BR]
+ skip_removal: false
+ - localegen: C.UTF-8
+ locales: [C.utf8, C.UTF-8]
+ skip_removal: true
+ - localegen: eo
+ locales: [eo]
+ skip_removal: false
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases
index 2bdcc0113..5e6585203 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases
@@ -4,4 +4,3 @@
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_dependent/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases
index 26ad5c244..12d1d6617 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases
@@ -3,4 +3,3 @@
# 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_dig/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases
index eb449a9cf..afda346c4 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases
@@ -3,4 +3,3 @@
# 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_etcd3/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases
index b9f3395f7..de1f51cb5 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases
@@ -10,5 +10,4 @@ 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_flattened/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases
index 0ac9bad98..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases
@@ -4,4 +4,3 @@
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_lmdb_kv/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases
index 66632fb4a..9c7febe24 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases
@@ -5,4 +5,3 @@
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_merge_variables/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases
index eb449a9cf..afda346c4 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases
@@ -3,4 +3,3 @@
# 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
index 52a38f4a5..4e66476be 100755
--- 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
@@ -11,3 +11,6 @@ ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
ANSIBLE_MERGE_VARIABLES_PATTERN_TYPE=suffix \
ansible-playbook test_with_env.yml "$@"
+
+ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
+ ansible-playbook -i test_inventory_all_hosts.yml test_all_hosts.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_all_hosts.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_all_hosts.yml
new file mode 100644
index 000000000..3070087bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_all_hosts.yml
@@ -0,0 +1,64 @@
+---
+# 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 (multiple hosts)
+ hosts: host0
+ gather_facts: false
+ tasks:
+ - name: Test merge dicts via all group
+ delegate_to: localhost
+ vars:
+ merged_dict: "{{ lookup('community.general.merge_variables', '__merge_dict_ex', pattern_type='suffix', groups=['all']) }}"
+ block:
+ - name: Test merge dicts via all group - Print the merged dict
+ ansible.builtin.debug:
+ msg: "{{ merged_dict }}"
+
+ - name: Test merge dicts via all group - Validate that the dict is complete
+ ansible.builtin.assert:
+ that:
+ - "(merged_dict.keys() | list | length) == 4"
+ - "'item1' in merged_dict"
+ - "'item2' in merged_dict"
+ - "'item3' in merged_dict"
+ - "'list_item' in merged_dict"
+ - "merged_dict.list_item | length == 3"
+ - name: Test merge dicts via two of three groups
+ delegate_to: localhost
+ vars:
+ merged_dict: "{{ lookup('community.general.merge_variables', '__merge_dict_in', pattern_type='suffix', groups=['dummy1', 'dummy2']) }}"
+ block:
+ - name: Test merge dicts via two of three groups - Print the merged dict
+ ansible.builtin.debug:
+ msg: "{{ merged_dict }}"
+
+ - name: Test merge dicts via two of three groups - Validate that the dict is complete
+ ansible.builtin.assert:
+ that:
+ - "(merged_dict.keys() | list | length) == 3"
+ - "'item1' in merged_dict"
+ - "'item2' in merged_dict"
+ - "'list_item' in merged_dict"
+ - "merged_dict.list_item | length == 2"
+ - name: Test merge dicts via two of three groups with inital value
+ delegate_to: localhost
+ vars:
+ initial_dict:
+ initial: initial_value
+ merged_dict: "{{ lookup('community.general.merge_variables', '__merge_dict_in', initial_value=initial_dict, pattern_type='suffix', groups=['dummy1', 'dummy2']) }}"
+ block:
+ - name: Test merge dicts via two of three groups with inital value - Print the merged dict
+ ansible.builtin.debug:
+ msg: "{{ merged_dict }}"
+
+ - name: Test merge dicts via two of three groups with inital value - Validate that the dict is complete
+ ansible.builtin.assert:
+ that:
+ - "(merged_dict.keys() | list | length) == 4"
+ - "'item1' in merged_dict"
+ - "'item2' in merged_dict"
+ - "'list_item' in merged_dict"
+ - "merged_dict.list_item | length == 2"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml
new file mode 100644
index 000000000..edf5a9e46
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml
@@ -0,0 +1,52 @@
+---
+# 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
+
+all:
+ hosts:
+ host0:
+ host1:
+ testdict1__merge_dict_ex:
+ item1: value1
+ list_item:
+ - test1
+
+ testdict2__merge_dict_ex:
+ item2: value2
+ list_item:
+ - test2
+
+ testdict__merge_dict_in:
+ item1: value1
+ list_item:
+ - test1
+ host2:
+ testdict3__merge_dict_ex:
+ item3: value3
+ list_item:
+ - test3
+
+ testdict__merge_dict_in:
+ item2: value2
+ list_item:
+ - test2
+
+ host3:
+ testdict__merge_dict_in:
+ item3: value3
+ list_item:
+ - test3
+
+dummy1:
+ hosts:
+ host1:
+
+dummy2:
+ hosts:
+ host2:
+
+dummy3:
+ hosts:
+ host3:
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases
index 0d4c5af3b..f02225028 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases
@@ -6,6 +6,5 @@ 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_random_pet/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases
index 0ac9bad98..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases
@@ -4,4 +4,3 @@
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/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases
index 0ac9bad98..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases
@@ -4,4 +4,3 @@
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/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases
index 0ac9bad98..dadd9f37a 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases
@@ -4,4 +4,3 @@
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/lvg/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml
index e14c48c3f..15af2d08c 100644
--- a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml
@@ -18,10 +18,20 @@
block:
- import_tasks: setup.yml
+ - import_tasks: setup_missing_pv.yml
+
- import_tasks: test_indempotency.yml
- import_tasks: test_grow_reduce.yml
- import_tasks: test_pvresize.yml
+
+ - import_tasks: test_active_change.yml
+
+ - import_tasks: test_active_create.yml
+
+ - import_tasks: test_uuid_reset.yml
always:
- import_tasks: teardown.yml
+
+ - import_tasks: teardown_missing_pv.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
index 3984b9fc3..45209c6a6 100644
--- a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml
@@ -4,8 +4,8 @@
# 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'
+ command: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=36"
+ with_sequence: 'count=4'
- name: "Show next free loop device"
command: "losetup -f"
@@ -21,7 +21,23 @@
- name: "Create loop device for file"
command: "losetup -f {{ remote_tmp_dir }}/img2"
+- name: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device3
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img3"
+
+- name: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device4
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img4"
+
- name: "Affect name on disk to work on"
set_fact:
loop_device1: "{{ loop_device1.stdout }}"
loop_device2: "{{ loop_device2.stdout }}"
+ loop_device3: "{{ loop_device3.stdout }}"
+ loop_device4: "{{ loop_device4.stdout }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup_missing_pv.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup_missing_pv.yml
new file mode 100644
index 000000000..863ef8757
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup_missing_pv.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: "Prepare VG for missing PV"
+ lvg:
+ vg: vg_with_missing_pv
+ pvs:
+ - "{{ loop_device3 }}"
+ - "{{ loop_device4 }}"
+
+- name: Save loop_device4 pvid
+ shell: "pvs -ouuid --noheadings {{ loop_device4 }} | xargs -n1 | tr -d '-'"
+ register: loop_device4_pvid_result
+
+- name: Detach loop_device4
+ command: "losetup -d {{ loop_device4 }}"
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
index de4957321..2d147dee0 100644
--- a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml
@@ -6,13 +6,25 @@
- name: Remove test volume group
lvg:
vg: testvg
+ force: true
state: absent
+- name: Remove LVM devices
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ - "{{ loop_device3 | default('') }}"
+ when:
+ - item|length > 0
+ command: "lvmdevices --deldev {{ item }}"
+ ignore_errors: true
+
- name: Detach loop devices
command: "losetup -d {{ item }}"
loop:
- "{{ loop_device1 | default('') }}"
- "{{ loop_device2 | default('') }}"
+ - "{{ loop_device3 | default('') }}"
when:
- item != ''
@@ -20,4 +32,4 @@
file:
path: "{{ remote_tmp_dir }}/img{{ item }}"
state: absent
- with_sequence: 'count=2'
+ with_sequence: 'count=4'
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown_missing_pv.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown_missing_pv.yml
new file mode 100644
index 000000000..4cff68003
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown_missing_pv.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
+
+- name: Remove loop_device4 LVM device
+ command: "lvmdevices --delpvid {{ loop_device4_pvid_result.stdout }}"
+ ignore_errors: true
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_change.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_change.yml
new file mode 100644
index 000000000..7df52683f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_change.yml
@@ -0,0 +1,163 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 logical volumes on volume group
+ loop:
+ - lv1
+ - lv2
+ lvol:
+ vg: testvg
+ lv: "{{ item }}"
+ size: 2m
+
+- name: Create snapshot volumes of origin logical volumes
+ loop:
+ - lv1
+ - lv2
+ lvol:
+ vg: testvg
+ lv: "{{ item }}"
+ snapshot: "{{ item }}_snap"
+ size: 50%ORIGIN
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: initial_lv_status_result
+
+- name: Assert all lv in testvg are active
+ loop: "{{ initial_lv_status_result.stdout_lines }}"
+ assert:
+ that:
+ - "'active' == item"
+
+- name: Deactivate volume group
+ lvg:
+ state: inactive
+ vg: testvg
+ register: vg_deactivate_result
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: deactivated_lv_status_result
+
+- name: Do all assertions to verify expected results
+ assert:
+ that:
+ - vg_deactivate_result is changed
+ - "'active' not in deactivated_lv_status_result.stdout"
+
+- name: Deactivate volume group again to verify idempotence
+ lvg:
+ state: inactive
+ vg: testvg
+ register: repeated_vg_deactivate_result
+
+- name: Verify vg deactivation idempontency
+ assert:
+ that:
+ - repeated_vg_deactivate_result is not changed
+
+- name: Activate volume group in check mode
+ lvg:
+ state: active
+ vg: testvg
+ register: check_mode_vg_activate_result
+ check_mode: true
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: check_mode_activate_lv_status_result
+
+- name: Verify VG activation in check mode changed without activating LVs
+ assert:
+ that:
+ - check_mode_vg_activate_result is changed
+ - "'active' not in check_mode_activate_lv_status_result.stdout"
+
+- name: Activate volume group
+ lvg:
+ state: active
+ vg: testvg
+ register: vg_activate_result
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: activate_lv_status_result
+
+- name: Verify vg activation
+ assert:
+ that:
+ - vg_activate_result is changed
+
+- name: Assert all lv in testvg are active
+ loop: "{{ activate_lv_status_result.stdout_lines }}"
+ assert:
+ that:
+ - "'active' == item"
+
+- name: Activate volume group again to verify idempontency
+ lvg:
+ state: active
+ vg: testvg
+ register: repeated_vg_activate_result
+
+- name: Verify vg activation idempontency
+ assert:
+ that:
+ - repeated_vg_activate_result is not changed
+
+- name: Deactivate lv2 in testvg
+ lvol:
+ vg: testvg
+ lv: lv2
+ active: false
+
+- name: Activate volume group again to verify partially activated vg activation
+ lvg:
+ state: active
+ vg: testvg
+ register: partial_vg_activate_result
+
+- name: Verify partially activated vg activation
+ assert:
+ that:
+ - partial_vg_activate_result is changed
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: activate_partial_lv_status_result
+
+- name: Assert all lv in testvg are active
+ loop: "{{ activate_partial_lv_status_result.stdout_lines }}"
+ assert:
+ that:
+ - "'active' == item"
+
+- name: Deactivate volume group in check mode
+ lvg:
+ state: inactive
+ vg: testvg
+ register: check_mode_vg_deactivate_result
+ check_mode: true
+
+- name: Collect all lv active status in testvg
+ shell: vgs -olv_active --noheadings testvg | xargs -n1
+ register: check_mode_deactivate_lv_status_result
+
+- name: Verify check mode vg deactivation changed
+ assert:
+ that:
+ - check_mode_vg_deactivate_result is changed
+
+- name: Assert all lv in testvg are still active
+ loop: "{{ check_mode_deactivate_lv_status_result.stdout_lines }}"
+ assert:
+ that:
+ - "'active' == item"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_create.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_create.yml
new file mode 100644
index 000000000..7ac1ffedd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_create.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: Collect vgcreate help
+ command: "vgcreate --help"
+ register: vgcreate_help_result
+
+- when: "'--setautoactivation' in vgcreate_help_result.stdout"
+ block:
+ - name: Create autoactivated volume group on disk device
+ lvg:
+ state: active
+ vg: vg_autoact_test
+ pvs: "{{ loop_device2 }}"
+
+ - name: Collect vg autoactivation status for vg_autoact_test
+ shell: vgs -oautoactivation --noheadings vg_autoact_test | xargs -n1
+ register: active_vg_autoact_status_result
+
+ - name: Assert vg autoactivation is set for vg_autoact_test
+ assert:
+ that: "'enabled' == active_vg_autoact_status_result.stdout"
+
+ - name: Remove vg_autoact_test for the next test
+ lvg:
+ state: absent
+ vg: vg_autoact_test
+ force: true
+
+ - name: Create auttoactivation disabled volume group on disk device
+ lvg:
+ state: inactive
+ vg: vg_autoact_test
+ pvs: "{{ loop_device2 }}"
+
+ - name: Collect vg autoactivation status for vg_autoact_test
+ shell: vgs -oautoactivation --noheadings vg_autoact_test | xargs -n1
+ register: inactive_vg_autoact_status_result
+
+ - name: Assert vg autoactivation disabled for vg_autoact_test
+ assert:
+ that: "inactive_vg_autoact_status_result.stdout | length == 0"
+
+ - name: Remove vg_autoact_test for the next test
+ lvg:
+ state: absent
+ vg: vg_autoact_test
+ force: true
+
+ - name: Create auttoactivation disabled by option volume group on disk device
+ lvg:
+ state: active
+ vg: vg_autoact_test
+ vg_options: "--setautoactivation n"
+ pvs: "{{ loop_device2 }}"
+
+ - name: Collect vg autoactivation status for vg_autoact_test
+ shell: vgs -oautoactivation --noheadings vg_autoact_test | xargs -n1
+ register: inactive_by_option_vg_autoact_status_result
+
+ - name: Assert vg autoactivation disabled by option for vg_autoact_test
+ assert:
+ that: "inactive_by_option_vg_autoact_status_result.stdout | length == 0"
+ always:
+ - name: Cleanup vg_autoact_test
+ lvg:
+ state: absent
+ vg: vg_autoact_test
+ force: true
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
index f15add91c..3f3b9dbdd 100644
--- 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
@@ -12,10 +12,10 @@
shell: vgs -v testvg -o pv_size --noheading --units b | xargs
register: cmd_result
-- name: Assert the testvg size is 8388608B
+- name: Assert the testvg size is 33554432B
assert:
that:
- - "'8388608B' == cmd_result.stdout"
+ - "'33554432B' == 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"
@@ -38,10 +38,10 @@
shell: vgs -v testvg -o pv_size --noheading --units b | xargs
register: cmd_result
-- name: Assert the testvg size is still 8388608B
+- name: Assert the testvg size is still 33554432B
assert:
that:
- - "'8388608B' == cmd_result.stdout"
+ - "'33554432B' == cmd_result.stdout"
- name: "Reruns lvg with pvresize:yes and check_mode:yes"
lvg:
@@ -60,10 +60,10 @@
shell: vgs -v testvg -o pv_size --noheading --units b | xargs
register: cmd_result
-- name: Assert the testvg size is still 8388608B
+- name: Assert the testvg size is still 33554432B
assert:
that:
- - "'8388608B' == cmd_result.stdout"
+ - "'33554432B' == cmd_result.stdout"
- name: "Reruns lvg with pvresize:yes"
lvg:
@@ -75,7 +75,7 @@
shell: vgs -v testvg -o pv_size --noheading --units b | xargs
register: cmd_result
-- name: Assert the testvg size is now 16777216B
+- name: Assert the testvg size is now 41943040B
assert:
that:
- - "'16777216B' == cmd_result.stdout"
+ - "'41943040B' == cmd_result.stdout"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_uuid_reset.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_uuid_reset.yml
new file mode 100644
index 000000000..8de50ace5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_uuid_reset.yml
@@ -0,0 +1,107 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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: Save testvg uuid
+ shell: vgs -ouuid --noheadings testvg | xargs -n1
+ register: orig_vg_uuid_cmd_result
+
+- name: Save pv uuid
+ shell: "pvs -ouuid --noheadings {{ loop_device1 }} | xargs -n1"
+ register: orig_pv_uuid_cmd_result
+
+- name: Deactivate and reset vg/pv uuid
+ lvg:
+ state: inactive
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+ reset_vg_uuid: true
+ reset_pv_uuid: true
+ register: vg_uuid_reset
+
+- name: Save testvg uuid
+ shell: vgs -ouuid --noheadings testvg | xargs -n1
+ register: new_vg_uuid_cmd_result
+
+- name: Save pv uuid
+ shell: "pvs -ouuid --noheadings {{ loop_device1 }} | xargs -n1"
+ register: new_pv_uuid_cmd_result
+
+- name: Do all assertions to verify expected results
+ assert:
+ that:
+ - vg_uuid_reset is changed
+ - orig_vg_uuid_cmd_result.stdout != new_vg_uuid_cmd_result.stdout
+ - orig_pv_uuid_cmd_result.stdout != new_pv_uuid_cmd_result.stdout
+
+- name: Reset vg uuid again to verify non-idempotence
+ lvg:
+ vg: testvg
+ reset_vg_uuid: true
+ register: repeat_vg_uuid_reset
+
+- name: Reset pv uuid again to verify non-idempotence
+ lvg:
+ vg: testvg
+ reset_pv_uuid: true
+ pvs: "{{ loop_device1 }}"
+ register: repeat_pv_uuid_reset
+
+- name: Save testvg uuid
+ shell: vgs -ouuid --noheadings testvg | xargs -n1
+ register: repeat_vg_uuid_cmd_result
+
+- name: Save pv uuid
+ shell: "pvs -ouuid --noheadings {{ loop_device1 }} | xargs -n1"
+ register: repeat_pv_uuid_cmd_result
+
+- name: Do all assertions to verify expected results
+ assert:
+ that:
+ - repeat_vg_uuid_reset is changed
+ - repeat_pv_uuid_reset is changed
+ - new_vg_uuid_cmd_result.stdout != repeat_vg_uuid_cmd_result.stdout
+ - new_pv_uuid_cmd_result.stdout != repeat_pv_uuid_cmd_result.stdout
+
+- name: Reset vg uuid in check mode
+ lvg:
+ vg: testvg
+ reset_vg_uuid: true
+ register: check_mode_vg_uuid_reset
+ check_mode: true
+
+- name: Reset pv uuid in check mode
+ lvg:
+ vg: testvg
+ reset_pv_uuid: true
+ pvs: "{{ loop_device1 }}"
+ register: check_mode_pv_uuid_reset
+ check_mode: true
+
+- name: Save testvg uuid
+ shell: vgs -ouuid --noheadings testvg | xargs -n1
+ register: check_mode_vg_uuid_cmd_result
+
+- name: Save pv uuid
+ shell: "pvs -ouuid --noheadings {{ loop_device1 }} | xargs -n1"
+ register: check_mode_pv_uuid_cmd_result
+
+- name: Do all assertions to verify expected results
+ assert:
+ that:
+ - check_mode_vg_uuid_reset is changed
+ - check_mode_pv_uuid_reset is changed
+ - check_mode_vg_uuid_cmd_result.stdout == repeat_vg_uuid_cmd_result.stdout
+ - check_mode_pv_uuid_cmd_result.stdout == repeat_pv_uuid_cmd_result.stdout
+
+- name: Activate volume group
+ lvg:
+ state: active
+ vg: testvg
+ register: vg_activate
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg_rename/aliases b/ansible_collections/community/general/tests/integration/targets/lvg_rename/aliases
new file mode 100644
index 000000000..64d439099
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) Contributors to the Ansible project
+# Based on the integraton test for the lvg module
+# GNU General Public License v3.0+ (see LICENSES/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_rename/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lvg_rename/meta/main.yml
new file mode 100644
index 000000000..90c5d5cb8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# Based on the integraton test for the lvg module
+# GNU General Public License v3.0+ (see LICENSES/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_rename/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/main.yml
new file mode 100644
index 000000000..18dd6f1ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/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) Contributors to the Ansible project
+# Based on the integraton test for the lvg module
+# GNU General Public License v3.0+ (see LICENSES/GPL-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)
+ when: ansible_system == 'Linux'
+ ansible.builtin.package:
+ name: lvm2
+ state: present
+
+- name: Test lvg_rename module
+ block:
+ - import_tasks: setup.yml
+
+ - import_tasks: test.yml
+
+ always:
+ - import_tasks: teardown.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/setup.yml
new file mode 100644
index 000000000..01721e42d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/setup.yml
@@ -0,0 +1,50 @@
+---
+# Copyright (c) Contributors to the Ansible project
+# Based on the integraton test for the lvg module
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 disk devices
+ with_sequence: 'count=2'
+ ansible.builtin.command:
+ cmd: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=10"
+ creates: "{{ remote_tmp_dir }}/img{{ item }}"
+
+- name: Show next free loop device
+ ansible.builtin.command:
+ cmd: "losetup -f"
+ changed_when: false
+ register: loop_device1
+
+- name: "Create loop device for file {{ remote_tmp_dir }}/img1"
+ ansible.builtin.command:
+ cmd: "losetup -f {{ remote_tmp_dir }}/img1"
+ changed_when: true
+
+- name: Show next free loop device
+ ansible.builtin.command:
+ cmd: "losetup -f"
+ changed_when: false
+ register: loop_device2
+
+- name: "Create loop device for file {{ remote_tmp_dir }}/img2"
+ ansible.builtin.command:
+ cmd: "losetup -f {{ remote_tmp_dir }}/img2"
+ changed_when: true
+
+- name: Affect name on disk to work on
+ ansible.builtin.set_fact:
+ loop_device1: "{{ loop_device1.stdout }}"
+ loop_device2: "{{ loop_device2.stdout }}"
+
+- name: "Create test volume group testvg on {{ loop_device1 }}"
+ community.general.lvg:
+ vg: "testvg"
+ state: present
+ pvs: "{{ loop_device1 }}"
+
+- name: "Create test volume group testvg2 on {{ loop_device2 }}"
+ community.general.lvg:
+ vg: "testvg2"
+ state: present
+ pvs: "{{ loop_device2 }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/teardown.yml b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/teardown.yml
new file mode 100644
index 000000000..71c33d56d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/teardown.yml
@@ -0,0 +1,46 @@
+---
+# Copyright (c) Contributors to the Ansible project
+# Based on the integraton test for the lvg module
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 test volume groups
+ ansible.builtin.command:
+ cmd: "pvs --noheadings -ovg_name {{ loop_device1 | default('') }} {{ loop_device2 | default('') }}"
+ register: test_vgs_output
+ changed_when: false
+
+- name: Remove test volume groups
+ loop: "{{ test_vgs_output.stdout_lines }}"
+ loop_control:
+ label: "{{ item | trim }}"
+ community.general.lvg:
+ vg: "{{ item | trim }}"
+ state: absent
+
+- name: Remove lvmdevices
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ when:
+ - item | length > 0
+ ansible.builtin.command:
+ cmd: "lvmdevices --deldev {{ item }}"
+ failed_when: false
+ changed_when: true
+
+- name: Detach loop devices
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ when:
+ - item | length > 0
+ ansible.builtin.command:
+ cmd: "losetup -d {{ item }}"
+ changed_when: true
+
+- name: Remove device files
+ with_sequence: 'count=2'
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}/img{{ item }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/test.yml
new file mode 100644
index 000000000..ab62b679b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/test.yml
@@ -0,0 +1,105 @@
+---
+# Copyright (c) Contributors to the Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Rename a VG in check mode
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_renamed
+ check_mode: true
+ register: check_mode_vg_rename
+
+- name: Check if testvg still exists
+ ansible.builtin.command:
+ cmd: vgs testvg
+ changed_when: false
+
+- name: Assert that renaming a VG is changed - check mode
+ assert:
+ that:
+ - check_mode_vg_rename is changed
+
+- name: Rename testvg to testvg_renamed
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_renamed
+ register: vg_renamed
+
+- name: Assert that renaming a VG is changed
+ assert:
+ that:
+ - vg_renamed is changed
+
+- name: Check if testvg does not exists
+ ansible.builtin.command:
+ cmd: vgs testvg
+ register: check_testvg_existence_result
+ failed_when: check_testvg_existence_result.rc == 0
+ changed_when: false
+
+- name: Check if testvg_renamed exists
+ ansible.builtin.command:
+ cmd: vgs testvg_renamed
+ changed_when: false
+
+- name: Rename testvg to testvg_renamed again for testing idempotency - check mode
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_renamed
+ check_mode: true
+ register: check_mode_vg_renamed_again
+
+- name: Rename testvg to testvg_renamed again for testing idempotency
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_renamed
+ register: vg_renamed_again
+
+- name: Assert that renaming a VG again is not changed
+ assert:
+ that:
+ - check_mode_vg_renamed_again is not changed
+ - vg_renamed_again is not changed
+
+- name: Rename a non-existing VG - check mode
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_ne
+ check_mode: true
+ ignore_errors: true
+ register: check_mode_ne_vg_rename
+
+- name: Rename a non-existing VG
+ community.general.lvg_rename:
+ vg: testvg
+ vg_new: testvg_ne
+ ignore_errors: true
+ register: ne_vg_rename
+
+- name: Assert that renaming a no-existing VG failed
+ assert:
+ that:
+ - check_mode_ne_vg_rename is failed
+ - ne_vg_rename is failed
+
+- name: Rename testvg_renamed to the existing testvg2 name - check mode
+ community.general.lvg_rename:
+ vg: testvg_renamed
+ vg_new: testvg2
+ check_mode: true
+ ignore_errors: true
+ register: check_mode_vg_rename_collision
+
+- name: Rename testvg_renamed to the existing testvg2 name
+ community.general.lvg_rename:
+ vg: testvg_renamed
+ vg_new: testvg2
+ ignore_errors: true
+ register: vg_rename_collision
+
+- name: Assert that renaming to an existing VG name failed
+ assert:
+ that:
+ - check_mode_vg_rename_collision is failed
+ - vg_rename_collision is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/lvol/aliases b/ansible_collections/community/general/tests/integration/targets/lvol/aliases
new file mode 100644
index 000000000..3b92ba75c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/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/lvol/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lvol/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/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/lvol/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/main.yml
new file mode 100644
index 000000000..0e3bfa1a3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/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: Install required packages (Linux)
+ package:
+ name: lvm2
+ state: present
+ when: ansible_system == 'Linux'
+
+- name: Test lvol module
+ block:
+ - import_tasks: setup.yml
+
+ - import_tasks: test_pvs.yml
+
+ always:
+ - import_tasks: teardown.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/lvol/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/setup.yml
new file mode 100644
index 000000000..195c50111
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/setup.yml
@@ -0,0 +1,57 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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=36"
+ with_sequence: 'count=4'
+
+- 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: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device3
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img3"
+
+- name: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device4
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img4"
+
+- name: "Set loop device names"
+ set_fact:
+ loop_device1: "{{ loop_device1.stdout }}"
+ loop_device2: "{{ loop_device2.stdout }}"
+ loop_device3: "{{ loop_device3.stdout }}"
+ loop_device4: "{{ loop_device4.stdout }}"
+
+- name: Create testvg1 volume group on disk devices
+ lvg:
+ vg: testvg1
+ pvs:
+ - "{{ loop_device1 }}"
+ - "{{ loop_device2 }}"
+
+- name: Create testvg2 volume group on disk devices
+ lvg:
+ vg: testvg2
+ pvs:
+ - "{{ loop_device3 }}"
+ - "{{ loop_device4 }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvol/tasks/teardown.yml b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/teardown.yml
new file mode 100644
index 000000000..a8080f874
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/teardown.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: Remove test volume groups
+ loop:
+ - testvg1
+ - testvg2
+ lvg:
+ vg: "{{ item }}"
+ force: true
+ state: absent
+
+- name: Remove LVM devices
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ - "{{ loop_device3 | default('') }}"
+ - "{{ loop_device4 | default('') }}"
+ when:
+ - item|length > 0
+ command: "lvmdevices --deldev {{ item }}"
+ ignore_errors: true
+
+- name: Detach loop devices
+ command: "losetup -d {{ item }}"
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ - "{{ loop_device3 | default('') }}"
+ - "{{ loop_device4 | default('') }}"
+ when:
+ - item != ''
+
+- name: Remove device files
+ file:
+ path: "{{ remote_tmp_dir }}/img{{ item }}"
+ state: absent
+ with_sequence: 'count=4'
diff --git a/ansible_collections/community/general/tests/integration/targets/lvol/tasks/test_pvs.yml b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/test_pvs.yml
new file mode 100644
index 000000000..c1cd3d1a8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvol/tasks/test_pvs.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 logical volume (testlv1) with pvs set as comma separated string
+ lvol:
+ vg: testvg1
+ lv: testlv1
+ size: 50%PVS
+ pvs: "{{ loop_device1 }},{{ loop_device2 }}"
+ register: css_pvs_create_testlv1_result
+
+- name: Assert logical volume (testlv1) created with pvs set as comma separated string
+ assert:
+ that:
+ - css_pvs_create_testlv1_result is success
+ - css_pvs_create_testlv1_result is changed
+
+- name: Create logical volume (testlv1) with pvs set as list
+ lvol:
+ vg: testvg1
+ lv: testlv1
+ size: 50%PVS
+ pvs:
+ - "{{ loop_device1 }}"
+ - "{{ loop_device2 }}"
+ register: list_pvs_create_testlv1_result
+
+- name: Assert logical volume (testlv1) creation idempotency with pvs set as list on second execution
+ assert:
+ that:
+ - list_pvs_create_testlv1_result is success
+ - list_pvs_create_testlv1_result is not changed
+
+- name: Create logical volume (testlv2) with pvs set as list
+ lvol:
+ vg: testvg2
+ lv: testlv2
+ size: 50%PVS
+ pvs:
+ - "{{ loop_device3 }}"
+ - "{{ loop_device4 }}"
+ register: list_pvs_create_testlv2_result
+
+- name: Assert logical volume (testlv2) created with pvs set as list
+ assert:
+ that:
+ - list_pvs_create_testlv2_result is success
+ - list_pvs_create_testlv2_result is changed
+
+- name: Create logical volume (testlv2) with pvs set as comma separated string
+ lvol:
+ vg: testvg2
+ lv: testlv2
+ size: 50%PVS
+ pvs: "{{ loop_device3 }},{{ loop_device4 }}"
+ register: css_pvs_create_testlv2_result
+
+- name: Assert logical volume (testlv2) creation idempotency with pvs set as comma separated string on second execution
+ assert:
+ that:
+ - css_pvs_create_testlv2_result is success
+ - css_pvs_create_testlv2_result is not changed
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
index 4f3f90a51..83c242ad2 100644
--- a/ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml
@@ -10,96 +10,101 @@
# 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
+- when:
+ # TODO: https://github.com/ansible-collections/community.general/issues/4656
+ - ansible_python.version.major != 3 or ansible_python.version.minor < 12
+ block:
-- name: Install test smtpserver
- copy:
- src: '{{ item }}'
- dest: '{{ remote_tmp_dir }}/{{ item }}'
- loop:
- - smtpserver.py
- - smtpserver.crt
- - smtpserver.key
+ # 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
-# 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: Install test smtpserver
+ copy:
+ src: '{{ item }}'
+ dest: '{{ remote_tmp_dir }}/{{ item }}'
+ loop:
+ - smtpserver.py
+ - smtpserver.crt
+ - smtpserver.key
-- name: Send a basic test-mail
- mail:
- port: 10025
- subject: Test mail 1 (smtp)
- secure: never
+ # 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 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 basic test-mail
+ mail:
+ port: 10025
+ subject: Test mail 1 (smtp)
+ 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
+ - 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
-# 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
+ - 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 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
+ # 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
-- fail:
- msg: Sending mail using starttls failed.
- when: smtpd_tls is succeeded and starttls_support is failed and tls_support is succeeded
+ # 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: Send mail using TLS failed.
- when: smtpd_tls is succeeded and tls_support is failed and starttls_support is succeeded
+ - fail:
+ msg: Sending mail using starttls failed.
+ when: smtpd_tls is succeeded and starttls_support is failed and tls_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
+ - 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/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml
index f659160dc..839620779 100644
--- a/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml
@@ -117,7 +117,7 @@
that:
- install_status.stat.exists == true
-- name: Unistall Rested
+- name: Uninstall Rested
mas:
id: 421879749
state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/aliases b/ansible_collections/community/general/tests/integration/targets/monit/aliases
index ca39d1353..c78104339 100644
--- a/ansible_collections/community/general/tests/integration/targets/monit/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/monit/aliases
@@ -9,6 +9,5 @@ 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/mssql_script/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml
index 6fa4d3501..481522216 100644
--- 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
@@ -49,6 +49,19 @@
login_port: "{{ mssql_port }}"
script: "SELECT 1"
+- name: Execute a malformed query
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: "SELCT 1"
+ failed_when: false
+ register: bad_query
+- assert:
+ that:
+ - bad_query.error.startswith('ProgrammingError')
+
- name: two batches with default output
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
@@ -135,6 +148,30 @@
- 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: Multiple batches with no resultsets and mixed-case GO
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: |
+ CREATE TABLE #integration56yH2 (c1 VARCHAR(10), c2 VARCHAR(10))
+ Go
+ INSERT INTO #integration56yH2 VALUES ('C1_VALUE1', 'C2_VALUE1')
+ gO
+ UPDATE #integration56yH2 SET c2 = 'C2_VALUE2' WHERE c1 = 'C1_VALUE1'
+ go
+ SELECT * from #integration56yH2
+ GO
+ DROP TABLE #integration56yH2
+ register: empty_batches
+- assert:
+ that:
+ - empty_batches.query_results | length == 5 # five batch results
+ - empty_batches.query_results[3][0] | length == 1 # one row in select
+ - empty_batches.query_results[3][0][0] | length == 2 # two columns in row
+ - empty_batches.query_results[3][0][0][1] == 'C2_VALUE2' # value has been updated
+
- name: Stored procedure may return multiple result sets
community.general.mssql_script:
login_user: "{{ mssql_login_user }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/aliases b/ansible_collections/community/general/tests/integration/targets/nomad/aliases
index ad2435c82..5886d4799 100644
--- a/ansible_collections/community/general/tests/integration/targets/nomad/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/aliases
@@ -8,3 +8,4 @@ destructive
skip/aix
skip/centos6
skip/freebsd
+disabled # TODO
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
index c8e83f602..0ab8a98d2 100644
--- a/ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml
@@ -12,10 +12,10 @@
# sample: node-v8.2.0-linux-x64.tar.xz
node_path: '{{ remote_dir }}/{{ nodejs_path }}/bin'
package: 'iconv-lite'
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
block:
- shell: npm --version
- environment:
- PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
register: npm_version
- debug:
@@ -24,11 +24,8 @@
- 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:
@@ -39,11 +36,8 @@
- 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
@@ -60,11 +54,8 @@
- 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
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/aliases b/ansible_collections/community/general/tests/integration/targets/odbc/aliases
index e8465c50e..91a616725 100644
--- a/ansible_collections/community/general/tests/integration/targets/odbc/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/aliases
@@ -9,4 +9,6 @@ skip/macos
skip/rhel8.0
skip/rhel9.0
skip/rhel9.1
+skip/rhel9.2
+skip/rhel9.3
skip/freebsd
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
index ce55ea8aa..af5f57cb2 100644
--- a/ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml
@@ -10,6 +10,7 @@
- when:
- ansible_os_family != 'Archlinux' # TODO install driver from AUR: https://aur.archlinux.org/packages/psqlodbc
+ - ansible_os_family != 'RedHat' or ansible_distribution_major_version != '7' # CentOS 7 stopped working
block:
#
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
index ffd5ac04c..3b2c1cedf 100644
--- 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
@@ -9,7 +9,7 @@
# GNU General Public License v3.0+ (see LICENSES/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
+# ENVIRONMENT PREPARACTION
- set_fact: test_number= 0
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
index f7bcb8944..3ca3180f0 100644
--- 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
@@ -21,7 +21,7 @@
- name: Test if state and value are required together
assert:
that:
- - "'following are missing: value' in '{{ missing_value['msg'] }}'"
+ - "'following are missing: value' in missing_value['msg']"
- name: Change value of AppleMeasurementUnits to centimeter in check_mode
osx_defaults:
@@ -194,7 +194,7 @@
register: test_data_types
- assert:
- that: "{{ item.changed }}"
+ that: "item is changed"
with_items: "{{ test_data_types.results }}"
- name: Use different data types and delete them
@@ -208,7 +208,7 @@
register: test_data_types
- assert:
- that: "{{ item.changed }}"
+ that: "item is changed"
with_items: "{{ test_data_types.results }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/pacman/handlers/main.yml
new file mode 100644
index 000000000..484482bba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/handlers/main.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 user yaybuilder
+ ansible.builtin.user:
+ name: yaybuilder
+ state: absent
+
+- name: Remove yay
+ ansible.builtin.package:
+ name: yay
+ state: absent
+
+- name: Remove packages for yay-become
+ ansible.builtin.package:
+ name:
+ - base-devel
+ - yay
+ - git
+ - nmap
+ state: 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
index a5f183236..f67950c75 100644
--- 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
@@ -7,11 +7,12 @@
package_name: ansible-test-foo
username: ansible-regular-user
block:
- - name: Install fakeroot
+ - name: Install dependencies
pacman:
state: present
name:
- fakeroot
+ - debugedit
- name: Create user
user:
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
index 12d28a2d3..1f6001a66 100644
--- a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml
@@ -17,3 +17,4 @@
- include_tasks: 'update_cache.yml'
- include_tasks: 'locally_installed_package.yml'
- include_tasks: 'reason.yml'
+ - include_tasks: 'yay-become.yml'
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
index 2271ebc03..a410775c2 100644
--- 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
@@ -4,13 +4,14 @@
# SPDX-License-Identifier: GPL-3.0-or-later
- vars:
- package_name: xinetd
- config_file: /etc/xinetd.conf
+ package_name: mdadm
+ config_file: /etc/mdadm.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'
@@ -32,6 +33,7 @@
pacman:
name: '{{ package_name }}'
state: absent
+
- name: Make sure {{config_file}}.pacsave exists
stat:
path: '{{config_file}}.pacsave'
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/yay-become.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/yay-become.yml
new file mode 100644
index 000000000..95698d5ce
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/yay-become.yml
@@ -0,0 +1,66 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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 is more convoluted that one might expect, because:
+# - yay is not available or installation in ArchLinux (as it is in Manjaro - issue 6184 reports using it)
+# - to install yay in ArchLinux requires building the package
+# - makepkg cannot be run as root, but the user running it must have sudo to install the resulting package
+
+- name: create user
+ ansible.builtin.user:
+ name: yaybuilder
+ state: present
+ notify: Remove user yaybuilder
+
+- name: grant sudo powers to builder
+ community.general.sudoers:
+ name: yaybuilder
+ user: yaybuilder
+ commands: ALL
+ nopassword: true
+
+- name: Install base packages
+ ansible.builtin.package:
+ name:
+ - base-devel
+ - git
+ - go
+ state: present
+ notify: Remove packages for yay-become
+
+- name: Hack permissions for the remote_tmp_dir
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}"
+ mode: '0777'
+
+- name: Create temp directory for builder
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}/builder"
+ owner: yaybuilder
+ state: directory
+ mode: '0755'
+
+- name: clone yay git repo
+ become: true
+ become_user: yaybuilder
+ ansible.builtin.git:
+ repo: https://aur.archlinux.org/yay.git
+ dest: "{{ remote_tmp_dir }}/builder/yay"
+ depth: 1
+
+- name: make package
+ become: true
+ become_user: yaybuilder
+ ansible.builtin.command:
+ chdir: "{{ remote_tmp_dir }}/builder/yay"
+ cmd: makepkg -si --noconfirm
+ notify: Remove yay
+
+- name: Install nmap
+ community.general.pacman:
+ name: nmap
+ state: present
+ executable: yay
+ extra_args: --builddir /var/cache/yay
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
index 2ba7f3754..c8feaacf3 100644
--- a/ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml
@@ -45,7 +45,7 @@
- name: Copy templated helper script
template:
- src: obtainpid.sh
+ src: obtainpid.sh.j2
dest: "{{ remote_tmp_dir }}/obtainpid.sh"
mode: 0755
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.j2
index ecbf56aab..ecbf56aab 100644
--- a/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh
+++ b/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx/aliases b/ansible_collections/community/general/tests/integration/targets/pipx/aliases
index 9f87ec348..66e6e1a3e 100644
--- a/ansible_collections/community/general/tests/integration/targets/pipx/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/pipx/aliases
@@ -6,3 +6,4 @@ azp/posix/2
destructive
skip/python2
skip/python3.5
+disabled # TODO
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
index 567405ec4..7eb0f11a6 100644
--- a/ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml
@@ -314,3 +314,28 @@
that:
- install_tox_sitewide is changed
- usrlocaltox.stat.exists
+
+##############################################################################
+# Test for issue 7497
+- name: ensure application pyinstaller is uninstalled
+ community.general.pipx:
+ name: pyinstaller
+ state: absent
+
+- name: Install Python Package pyinstaller
+ community.general.pipx:
+ name: pyinstaller
+ state: present
+ system_site_packages: true
+ pip_args: "--no-cache-dir"
+ register: install_pyinstaller
+
+- name: cleanup pyinstaller
+ community.general.pipx:
+ name: pyinstaller
+ state: absent
+
+- name: check assertions
+ assert:
+ that:
+ - install_pyinstaller is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases b/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases
index a28278bbc..e262b485a 100644
--- a/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases
@@ -6,3 +6,4 @@ azp/posix/3
destructive
skip/python2
skip/python3.5
+disabled # TODO
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
index 0c8001899..9d4ecf8bb 100644
--- a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml
@@ -515,11 +515,18 @@
# NOTE: FreeBSD 13.2 fails to update the package catalogue for unknown reasons (someone with FreeBSD
# knowledge has to take a look)
#
+ # NOTE: FreeBSD 13.3 fails to update the package catalogue for unknown reasons (someone with FreeBSD
+ # knowledge has to take a look)
+ #
+ # NOTE: FreeBSD 14.0 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', '>=')
+ or (ansible_distribution_version is version('13.4', '>=') and ansible_distribution_version is version('14.0', '<'))
+ or ansible_distribution_version is version('14.1', '>=')
block:
- name: Setup testjail
include_tasks: setup-testjail.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/pnpm/aliases b/ansible_collections/community/general/tests/integration/targets/pnpm/aliases
new file mode 100644
index 000000000..afeb1a6ee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pnpm/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/macos
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/pnpm/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/pnpm/meta/main.yml
new file mode 100644
index 000000000..6147ad33e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pnpm/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/pnpm/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pnpm/tasks/main.yml
new file mode 100644
index 000000000..10f42618f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pnpm/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 #
+####################################################################
+
+# test code for the pnpm module
+# Copyright (c) 2023 Aritra Sen <aretrosen@proton.me>
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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
+
+- name: Run tests on OSes
+ ansible.builtin.include_tasks: run.yml
+ vars:
+ ansible_system_os: "{{ ansible_system | lower }}"
+ nodejs_version: "{{ item.node_version }}"
+ nodejs_path: "node-v{{ nodejs_version }}-{{ ansible_system_os }}-x{{ ansible_userspace_bits }}"
+ pnpm_version: "{{ item.pnpm_version }}"
+ pnpm_path: "pnpm-{{ 'macos' if ansible_system_os == 'darwin' else 'linuxstatic' }}-x{{ ansible_userspace_bits }}"
+ with_items:
+ - { node_version: 16.20.0, pnpm_version: 8.7.0 }
+ when:
+ - not(ansible_distribution == 'Alpine') and not(ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6')
diff --git a/ansible_collections/community/general/tests/integration/targets/pnpm/tasks/run.yml b/ansible_collections/community/general/tests/integration/targets/pnpm/tasks/run.yml
new file mode 100644
index 000000000..66f5eb622
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pnpm/tasks/run.yml
@@ -0,0 +1,322 @@
+---
+# Copyright (c) 2023 Aritra Sen <aretrosen@proton.me>
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 nodejs
+ ansible.builtin.unarchive:
+ src: "https://nodejs.org/dist/v{{ nodejs_version }}/{{ nodejs_path }}.tar.gz"
+ dest: "{{ remote_tmp_dir }}"
+ remote_src: true
+ creates: "{{ remote_tmp_dir }}/{{ nodejs_path }}.tar.gz"
+
+- name: Create a temporary directory for pnpm binary
+ ansible.builtin.tempfile:
+ state: directory
+ register: tmp_dir
+
+- name: Download pnpm binary to the temporary directory
+ ansible.builtin.get_url:
+ url: "https://github.com/pnpm/pnpm/releases/download/v{{ pnpm_version }}/{{ pnpm_path }}"
+ dest: "{{ tmp_dir.path }}/pnpm"
+ mode: "755"
+
+- name: Setting up pnpm via command
+ ansible.builtin.command: "{{ tmp_dir.path }}/pnpm setup --force"
+ environment:
+ PNPM_HOME: "{{ ansible_env.HOME }}/.local/share/pnpm"
+ SHELL: /bin/sh
+ ENV: "{{ ansible_env.HOME }}/.shrc"
+
+- name: Remove the temporary directory
+ ansible.builtin.file:
+ path: "{{ tmp_dir.path }}"
+ state: absent
+
+- name: Remove any previous Nodejs modules
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}/node_modules"
+ state: absent
+
+- name: CI tests to run
+ vars:
+ node_bin_path: "{{ remote_tmp_dir }}/{{ nodejs_path }}/bin"
+ pnpm_bin_path: "{{ ansible_env.HOME }}/.local/share/pnpm"
+ package: "tailwindcss"
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+
+ block:
+ - name: Create dummy package.json
+ ansible.builtin.template:
+ src: package.j2
+ dest: "{{ remote_tmp_dir }}/package.json"
+ mode: "644"
+
+ - name: Install reading-time package via package.json
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: present
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+
+ - name: Install the same package from package.json again
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ name: "reading-time"
+ state: present
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_install
+
+ - name: Assert that result is not changed
+ ansible.builtin.assert:
+ that:
+ - not (pnpm_install is changed)
+
+ - name: Install all packages in check mode
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: present
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ check_mode: true
+ register: pnpm_install_check
+
+ - name: Verify test pnpm global installation in check mode
+ ansible.builtin.assert:
+ that:
+ - pnpm_install_check.err is defined
+ - pnpm_install_check.out is defined
+ - pnpm_install_check.err is none
+ - pnpm_install_check.out is none
+
+ - name: Install package without dependency
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: present
+ name: "{{ package }}"
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_install
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_install is success
+ - pnpm_install is changed
+
+ - name: Reinstall package without dependency
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: present
+ name: "{{ package }}"
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_reinstall
+
+ - name: Assert that there is no change
+ ansible.builtin.assert:
+ that:
+ - pnpm_reinstall is success
+ - not (pnpm_reinstall is changed)
+
+ - name: Reinstall package
+ pnpm:
+ path: "{{ remote_tmp_dir }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: latest
+ name: "{{ package }}"
+ environment:
+ PATH: "{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_fix_install
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_fix_install is success
+ - pnpm_fix_install is not changed
+
+ - name: Install package with version, without executable path
+ pnpm:
+ name: "{{ package }}"
+ version: 0.1.3
+ path: "{{ remote_tmp_dir }}"
+ state: present
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_install
+
+ - name: Assert that package with version is installed
+ ansible.builtin.assert:
+ that:
+ - pnpm_install is success
+ - pnpm_install is changed
+
+ - name: Reinstall package with version, without explicit executable path
+ pnpm:
+ name: "{{ package }}"
+ version: 0.1.3
+ path: "{{ remote_tmp_dir }}"
+ state: present
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_reinstall
+
+ - name: Assert that there is no change
+ ansible.builtin.assert:
+ that:
+ - pnpm_reinstall is success
+ - not (pnpm_reinstall is changed)
+
+ - name: Update package, without executable path
+ pnpm:
+ name: "{{ package }}"
+ path: "{{ remote_tmp_dir }}"
+ state: latest
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_update
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_update is success
+ - pnpm_update is changed
+
+ - name: Remove package, without executable path
+ pnpm:
+ name: "{{ package }}"
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_absent
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_absent is success
+ - pnpm_absent is changed
+
+ - name: Install package with version and alias, without executable path
+ pnpm:
+ name: "{{ package }}"
+ alias: tailwind-1
+ version: 0.1.3
+ path: "{{ remote_tmp_dir }}"
+ state: present
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_install
+
+ - name: Assert that package with version and alias is installed
+ ansible.builtin.assert:
+ that:
+ - pnpm_install is success
+ - pnpm_install is changed
+
+ - name: Reinstall package with version and alias, without explicit executable path
+ pnpm:
+ name: "{{ package }}"
+ alias: tailwind-1
+ version: 0.1.3
+ path: "{{ remote_tmp_dir }}"
+ state: present
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_reinstall
+
+ - name: Assert that there is no change
+ ansible.builtin.assert:
+ that:
+ - pnpm_reinstall is success
+ - not (pnpm_reinstall is changed)
+
+ - name: Remove package with alias, without executable path
+ pnpm:
+ name: tailwindcss
+ alias: tailwind-1
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ register: pnpm_absent
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_absent is success
+ - pnpm_absent is changed
+
+ - name: Install package without dependency globally
+ pnpm:
+ name: "{{ package }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ state: present
+ global: true
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ PNPM_HOME: "{{ pnpm_bin_path }}"
+ register: pnpm_install
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_install is success
+ - pnpm_install is changed
+
+ - name: Reinstall package globally, without explicit executable path
+ pnpm:
+ name: "{{ package }}"
+ state: present
+ global: true
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ PNPM_HOME: "{{ pnpm_bin_path }}"
+ register: pnpm_reinstall
+
+ - name: Assert that there is no change
+ ansible.builtin.assert:
+ that:
+ - pnpm_reinstall is success
+ - not (pnpm_reinstall is changed)
+
+ - name: Updating package globally, without explicit executable path
+ pnpm:
+ name: "{{ package }}"
+ state: latest
+ global: true
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ PNPM_HOME: "{{ pnpm_bin_path }}"
+ register: pnpm_reinstall
+
+ - name: Assert that there is no change
+ ansible.builtin.assert:
+ that:
+ - pnpm_reinstall is success
+ - pnpm_reinstall is not changed
+
+ - name: Remove package without dependency globally
+ pnpm:
+ name: "{{ package }}"
+ executable: "{{ pnpm_bin_path }}/pnpm"
+ global: true
+ state: absent
+ environment:
+ PATH: "{{ pnpm_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}"
+ PNPM_HOME: "{{ pnpm_bin_path }}"
+ register: pnpm_absent
+
+ - name: Assert that result is changed and successful
+ ansible.builtin.assert:
+ that:
+ - pnpm_absent is success
+ - pnpm_absent is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/pnpm/templates/package.j2 b/ansible_collections/community/general/tests/integration/targets/pnpm/templates/package.j2
new file mode 100644
index 000000000..429ea9bee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pnpm/templates/package.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
+#}
+{
+ "name": "ansible-pnpm-testing",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "reading-time": "^1.5.0"
+ }
+}
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
index 22d7fcd29..1b529d111 100644
--- a/ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml
@@ -129,6 +129,25 @@
- results_storage.proxmox_storages|length == 1
- results_storage.proxmox_storages[0].storage == "{{ storage }}"
+- name: List content on storage
+ proxmox_storage_contents_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 }}"
+ node: "{{ node }}"
+ content: images
+ register: results_list_storage
+
+- assert:
+ that:
+ - results_storage is not changed
+ - results_storage.proxmox_storage_content is defined
+ - results_storage.proxmox_storage_content |length == 1
+
- name: VM creation
tags: [ 'create' ]
block:
@@ -577,3 +596,20 @@
- results_kvm_destroy is changed
- results_kvm_destroy.vmid == {{ vmid }}
- results_kvm_destroy.msg == "VM {{ vmid }} removed"
+
+- name: Retrieve information about nodes
+ proxmox_node_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_nodes is defined
+ - results.proxmox_nodes|length >= 1
+ - results.proxmox_nodes[0].type == 'node'
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox_pool/aliases b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/aliases
new file mode 100644
index 000000000..525dcd332
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/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
+
+unsupported
+proxmox_pool
+proxmox_pool_member
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox_pool/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/defaults/main.yml
new file mode 100644
index 000000000..5a518ac73
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/defaults/main.yml
@@ -0,0 +1,7 @@
+# Copyright (c) 2023, Sergei Antipov <greendayonfire at 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
+
+poolid: test
+member: local
+member_type: storage
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox_pool/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/tasks/main.yml
new file mode 100644
index 000000000..2b22960f2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox_pool/tasks/main.yml
@@ -0,0 +1,220 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2023, Sergei Antipov <greendayonfire at 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: Proxmox VE pool and pool membership management
+ tags: ["pool"]
+ block:
+ - name: Make sure poolid parameter is not missing
+ proxmox_pool:
+ 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 }}"
+ ignore_errors: true
+ register: result
+
+ - assert:
+ that:
+ - result is failed
+ - "'missing required arguments: poolid' in result.msg"
+
+ - name: Create pool (Check)
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ check_mode: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+
+ - name: Create pool
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - result.poolid == "{{ poolid }}"
+
+ - name: Delete pool (Check)
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ state: absent
+ check_mode: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+
+ - name: Delete non-existing pool should do nothing
+ proxmox_pool:
+ 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 }}"
+ poolid: "non-existing-poolid"
+ state: absent
+ register: result
+
+ - assert:
+ that:
+ - result is not changed
+ - result is success
+
+ - name: Deletion of non-empty pool fails
+ block:
+ - name: Add storage into pool
+ proxmox_pool_member:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ member: "{{ member }}"
+ type: "{{ member_type }}"
+ diff: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - "'{{ member }}' in result.diff.after.members"
+
+ - name: Add non-existing storage into pool should fail
+ proxmox_pool_member:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ member: "non-existing-storage"
+ type: "{{ member_type }}"
+ ignore_errors: true
+ register: result
+
+ - assert:
+ that:
+ - result is failed
+ - "'Storage non-existing-storage doesn\\'t exist in the cluster' in result.msg"
+
+ - name: Delete non-empty pool
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ state: absent
+ ignore_errors: true
+ register: result
+
+ - assert:
+ that:
+ - result is failed
+ - "'Please remove members from pool first.' in result.msg"
+
+ - name: Delete storage from the pool
+ proxmox_pool_member:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ member: "{{ member }}"
+ type: "{{ member_type }}"
+ state: absent
+ register: result
+
+ - assert:
+ that:
+ - result is success
+ - result is changed
+
+ rescue:
+ - name: Delete storage from the pool if it is added
+ proxmox_pool_member:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ member: "{{ member }}"
+ type: "{{ member_type }}"
+ state: absent
+ ignore_errors: true
+
+ - name: Delete pool
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ state: absent
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - result.poolid == "{{ poolid }}"
+
+ rescue:
+ - name: Delete test pool if it is created
+ proxmox_pool:
+ 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 }}"
+ poolid: "{{ poolid }}"
+ state: absent
+ ignore_errors: true
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox_template/aliases b/ansible_collections/community/general/tests/integration/targets/proxmox_template/aliases
new file mode 100644
index 000000000..5d9af8101
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox_template/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
+
+unsupported
+proxmox_template
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox_template/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/proxmox_template/tasks/main.yml
new file mode 100644
index 000000000..2d1187e89
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox_template/tasks/main.yml
@@ -0,0 +1,136 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2023, Sergei Antipov <greendayonfire at 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: Proxmox VE virtual machines templates management
+ tags: ['template']
+ vars:
+ filename: /tmp/dummy.iso
+ block:
+ - name: Create dummy ISO file
+ ansible.builtin.command:
+ cmd: 'truncate -s 300M {{ filename }}'
+
+ - name: Delete requests_toolbelt module if it is installed
+ ansible.builtin.pip:
+ name: requests_toolbelt
+ state: absent
+
+ - name: Install latest proxmoxer
+ ansible.builtin.pip:
+ name: proxmoxer
+ state: latest
+
+ - name: Upload ISO as template to Proxmox VE cluster should fail
+ proxmox_template:
+ 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 }}'
+ src: '{{ filename }}'
+ content_type: iso
+ force: true
+ register: result
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+ - result.msg is match('\'requests_toolbelt\' module is required to upload files larger than 256MB')
+
+ - name: Install old (1.1.2) version of proxmoxer
+ ansible.builtin.pip:
+ name: proxmoxer==1.1.1
+ state: present
+
+ - name: Upload ISO as template to Proxmox VE cluster should be successful
+ proxmox_template:
+ 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 }}'
+ src: '{{ filename }}'
+ content_type: iso
+ force: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - result.msg is match('template with volid=local:iso/dummy.iso uploaded')
+
+ - name: Install latest proxmoxer
+ ansible.builtin.pip:
+ name: proxmoxer
+ state: latest
+
+ - name: Make smaller dummy file
+ ansible.builtin.command:
+ cmd: 'truncate -s 128M {{ filename }}'
+
+ - name: Upload ISO as template to Proxmox VE cluster should be successful
+ proxmox_template:
+ 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 }}'
+ src: '{{ filename }}'
+ content_type: iso
+ force: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - result.msg is match('template with volid=local:iso/dummy.iso uploaded')
+
+ - name: Install requests_toolbelt
+ ansible.builtin.pip:
+ name: requests_toolbelt
+ state: present
+
+ - name: Make big dummy file
+ ansible.builtin.command:
+ cmd: 'truncate -s 300M {{ filename }}'
+
+ - name: Upload ISO as template to Proxmox VE cluster should be successful
+ proxmox_template:
+ 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 }}'
+ src: '{{ filename }}'
+ content_type: iso
+ force: true
+ register: result
+
+ - assert:
+ that:
+ - result is changed
+ - result is success
+ - result.msg is match('template with volid=local:iso/dummy.iso uploaded')
+
+ always:
+ - name: Delete ISO file from host
+ ansible.builtin.file:
+ path: '{{ filename }}'
+ state: absent
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
index 5a674b801..b2429e39f 100644
--- 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
@@ -23,7 +23,7 @@
commercial_type: '{{ scaleway_commerial_type }}'
wait: true
-- name: Get server informations of the first page
+- name: Get server information of the first page
scaleway_server_info:
region: par1
query_parameters:
@@ -37,7 +37,7 @@
that:
- first_page is success
-- name: Get server informations of the second page
+- name: Get server information of the second page
scaleway_server_info:
region: par1
query_parameters:
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
index 91cea20f3..84d733a10 100644
--- 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
@@ -159,7 +159,7 @@
- cr_deletion_task is success
- cr_deletion_task is changed
-- name: Delete container regitry (Confirmation)
+- name: Delete container registry (Confirmation)
community.general.scaleway_container_registry:
state: absent
name: '{{ name }}'
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
index 2cdf34fdd..3dfe20f37 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get image information and register it in a variable
scaleway_image_info:
region: par1
register: images
@@ -22,7 +22,7 @@
that:
- images is success
-- name: Get image informations from ams1 and register it in a variable
+- name: Get image information from ams1 and register it in a variable
scaleway_image_info:
region: ams1
register: images_ams1
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
index b560b5658..6aad9b52e 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get ip information and register it in a variable
scaleway_ip_info:
region: par1
register: ips
@@ -22,7 +22,7 @@
that:
- ips is success
-- name: Get ip informations and register it in a variable
+- name: Get ip information and register it in a variable
scaleway_ip_info:
region: ams1
register: ips_ams1
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
index 7326ca226..247a4012b 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get organization information and register it in a variable
scaleway_organization_info:
register: organizations
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
index 8029a1e9a..608d76409 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get security group information and register it in a variable
scaleway_security_group_info:
region: par1
register: security_groups
@@ -22,7 +22,7 @@
that:
- security_groups is success
-- name: Get security group informations and register it in a variable (AMS1)
+- name: Get security group information and register it in a variable (AMS1)
scaleway_security_group_info:
region: ams1
register: ams1_security_groups
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
index 7274e8a85..516b2df0e 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get server information and register it in a variable
scaleway_server_info:
region: par1
register: servers
@@ -22,7 +22,7 @@
that:
- servers is success
-- name: Get server informations and register it in a variable
+- name: Get server information and register it in a variable
scaleway_server_info:
region: ams1
register: ams1_servers
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
index 44f15d515..f80a9ced1 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get snapshot information and register it in a variable
scaleway_snapshot_info:
region: par1
register: snapshots
@@ -22,7 +22,7 @@
that:
- snapshots is success
-- name: Get snapshot informations and register it in a variable (AMS1)
+- name: Get snapshot information and register it in a variable (AMS1)
scaleway_snapshot_info:
region: ams1
register: ams1_snapshots
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
index 45995a54c..2202e6bf9 100644
--- 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
@@ -8,7 +8,7 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Get volume information and register it in a variable
scaleway_volume_info:
region: par1
register: volumes
@@ -22,7 +22,7 @@
that:
- volumes is success
-- name: Get volume informations and register it in a variable (AMS1)
+- name: Get volume information and register it in a variable (AMS1)
scaleway_volume_info:
region: ams1
register: ams1_volumes
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
index 283496714..52e13e3c4 100644
--- 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
@@ -3,17 +3,29 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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 python requests
+ ansible.builtin.pip:
+ name:
+ - requests
+ state: absent
+
+- name: Stop docker service
+ become: true
+ ansible.builtin.service:
+ name: docker
+ state: stopped
+
- name: Remove Docker packages
- package:
+ ansible.builtin.package:
name: "{{ docker_packages }}"
state: absent
- name: "D-Fedora : Remove repository"
- file:
+ ansible.builtin.file:
path: /etc/yum.repos.d/docker-ce.repo
state: absent
- name: "D-Fedora : Remove dnf-plugins-core"
- package:
+ ansible.builtin.package:
name: dnf-plugins-core
state: absent
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
index 4f41da31a..19bc7aa8c 100644
--- 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
@@ -41,6 +41,7 @@
ansible.builtin.service:
name: docker
state: started
+ notify: Stop docker service
- name: Cheat on the docker socket permissions
become: true
@@ -53,3 +54,4 @@
name:
- requests
state: present
+ notify: Remove python requests
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
index fe6b9cd02..1da52e225 100644
--- 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
@@ -50,7 +50,7 @@
state: present
# Check if re-installing etcd3 is required
- - name: Check if etcd3ctl exists for re-use.
+ - name: Check if etcd3ctl exists for reuse.
shell: "ETCDCTL_API=3 {{ etcd3_path }}/etcdctl --endpoints=localhost:2379 get foo"
args:
executable: /bin/bash
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
index 2ab57d59d..9f156425d 100644
--- 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
@@ -16,11 +16,19 @@
}}
- name: Include OS-specific variables
- include_vars: '{{ ansible_os_family }}.yml'
+ include_vars: '{{ lookup("first_found", params) }}'
+ vars:
+ params:
+ files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml'
+ - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml'
+ - '{{ ansible_os_family }}.yml'
+ paths:
+ - '{{ role_path }}/vars'
when: has_java_keytool
- name: Install keytool
package:
- name: '{{ keytool_package_name }}'
+ name: '{{ keytool_package_names }}'
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
index 4ff75ae8c..c314c80ba 100644
--- 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
@@ -3,4 +3,5 @@
# GNU General Public License v3.0+ (see LICENSES/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
+keytool_package_names:
+ - 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
index 9e29065b3..b342911b6 100644
--- 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
@@ -3,4 +3,5 @@
# GNU General Public License v3.0+ (see LICENSES/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
+keytool_package_names:
+ - jre11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian-12.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian-12.yml
new file mode 100644
index 000000000..17f8a53d0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian-12.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
+
+keytool_package_names:
+ - ca-certificates-java
+ - openjdk-17-jre-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
index 30ae5cd04..cb5551a58 100644
--- 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
@@ -3,4 +3,5 @@
# GNU General Public License v3.0+ (see LICENSES/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
+keytool_package_names:
+ - 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
index c200091f8..8f4126e5d 100644
--- 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
@@ -3,4 +3,5 @@
# GNU General Public License v3.0+ (see LICENSES/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
+keytool_package_names:
+ - 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
index c200091f8..8f4126e5d 100644
--- 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
@@ -3,4 +3,5 @@
# GNU General Public License v3.0+ (see LICENSES/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
+keytool_package_names:
+ - java-11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif
new file mode 100644
index 000000000..fc97e5f5c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif
@@ -0,0 +1,15 @@
+dn: cn=config
+add: olcTLSCACertificateFile
+olcTLSCACertificateFile: /usr/local/share/ca-certificates/ca.crt
+-
+add: olcTLSCertificateFile
+olcTLSCertificateFile: /etc/ldap/localhost.crt
+-
+add: olcTLSCertificateKeyFile
+olcTLSCertificateKeyFile: /etc/ldap/localhost.key
+-
+add: olcAuthzRegexp
+olcAuthzRegexp: {0}"UID=([^,]*)" uid=$1,ou=users,dc=example,dc=com
+-
+add: olcTLSVerifyClient
+olcTLSVerifyClient: allow
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif.license b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_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/files/initial_config.ldif b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif
index 8f8c537bd..cb21f2cfd 100644
--- 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
@@ -18,5 +18,24 @@ homeDirectory: /home/ldaptest
cn: LDAP Test
gecos: LDAP Test
displayName: LDAP Test
+userPassword: test1pass!
mail: ldap.test@example.com
sn: Test
+
+dn: uid=second,ou=users,dc=example,dc=com
+uid: second
+uidNumber: 1112
+gidNUmber: 102
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+loginShell: /bin/sh
+homeDirectory: /home/second
+cn: Second Test
+gecos: Second Test
+displayName: Second Test
+mail: second.test@example.com
+sn: Test
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
index 25077de16..00f8f6a10 100644
--- 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
@@ -44,6 +44,22 @@
cmd: "export DEBIAN_FRONTEND=noninteractive; cat /root/debconf-slapd.conf | debconf-set-selections; dpkg-reconfigure -f noninteractive slapd"
creates: "/root/slapd_configured"
+ - name: Enable secure ldap
+ lineinfile:
+ path: /etc/default/slapd
+ regexp: "^SLAPD_SERVICES"
+ line: 'SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"'
+
+ - name: Create certificates
+ shell: |
+ openssl req -x509 -batch -sha256 -days 1825 -newkey rsa:2048 -nodes -keyout /root/ca.key -out /usr/local/share/ca-certificates/ca.crt
+ openssl req -batch -sha256 -days 365 -newkey rsa:2048 -subj "/CN=$(hostname)" -addext "subjectAltName = DNS:localhost" -nodes -keyout /etc/ldap/localhost.key -out /etc/ldap/localhost.csr
+ openssl x509 -req -CA /usr/local/share/ca-certificates/ca.crt -CAkey /root/ca.key -CAcreateserial -in /etc/ldap/localhost.csr -out /etc/ldap/localhost.crt
+ chgrp openldap /etc/ldap/localhost.key
+ chmod 0640 /etc/ldap/localhost.key
+ openssl req -batch -sha256 -days 365 -newkey rsa:2048 -subj "/UID=ldaptest" -nodes -keyout /root/user.key -out /root/user.csr
+ openssl x509 -req -CA /usr/local/share/ca-certificates/ca.crt -CAkey /root/ca.key -CAcreateserial -in /root/user.csr -out /root/user.crt
+
- name: Start OpenLDAP service
become: true
service:
@@ -61,10 +77,14 @@
mode: '0644'
loop:
- rootpw_cnconfig.ldif
+ - cert_cnconfig.ldif
- initial_config.ldif
- name: Configure admin password for cn=config
- shell: "ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/rootpw_cnconfig.ldif"
+ shell: "ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/{{ item }}"
+ loop:
+ - rootpw_cnconfig.ldif
+ - cert_cnconfig.ldif
- name: Add initial config
become: true
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
index fc75f84df..f471cc19a 100644
--- 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
@@ -21,3 +21,8 @@
update_cache: true
upgrade: true
when: archlinux_upgrade_tag is changed
+
+- name: Remove EXTERNALLY-MANAGED file
+ file:
+ path: /usr/lib/python{{ ansible_python.version.major }}.{{ ansible_python.version.minor }}/EXTERNALLY-MANAGED
+ state: absent
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
index 3dac4a098..99668ebc9 100644
--- 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
@@ -127,6 +127,32 @@
seconds: 5
when: ansible_os_family == 'Suse'
+- name: Make installable on Arch
+ community.general.ini_file:
+ path: /usr/lib/systemd/system/postgresql.service
+ section: Service
+ option: "{{ item }}"
+ state: absent
+ loop:
+ - PrivateTmp
+ - ProtectHome
+ - ProtectSystem
+ - NoNewPrivileges
+ - ProtectControlGroups
+ - ProtectKernelModules
+ - ProtectKernelTunables
+ - PrivateDevices
+ - RestrictAddressFamilies
+ - RestrictNamespaces
+ - RestrictRealtime
+ - SystemCallArchitectures
+ when: ansible_distribution == 'Archlinux'
+
+- name: Make installable on Arch
+ systemd:
+ daemon_reload: true
+ when: ansible_distribution == 'Archlinux'
+
- name: Initialize postgres (Suse)
service: name=postgresql state=started
when: ansible_os_family == 'Suse'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-12-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-12-py3.yml
new file mode 100644
index 000000000..c92240237
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-12-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/15/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/15/main"
+pg_ver: 15
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.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-9.3.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.3.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.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_tls/files/ca_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem
index 130e0a2da..a438d9266 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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_tls/files/ca_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem
index d9dc5ca0f..0a950eda0 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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_tls/files/client_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem
index 9e956e6b0..501d83897 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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_tls/files/client_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem
index 3848ad7cf..850260a87 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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_tls/files/server_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem
index b714ddbfb..4a0ebc6ec 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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_tls/files/server_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem
index ec0134993..c79ab6480 100644
--- 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
@@ -1,7 +1,3 @@
-# Copyright (c) Ansible Project
-# GNU General Public License v3.0+ (see LICENSES/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
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem.license b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem.license
new file mode 100644
index 000000000..a1390a69e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem.license
@@ -0,0 +1,3 @@
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/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/shutdown/aliases b/ansible_collections/community/general/tests/integration/targets/shutdown/aliases
index afda346c4..428e8289d 100644
--- a/ansible_collections/community/general/tests/integration/targets/shutdown/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/shutdown/aliases
@@ -3,3 +3,4 @@
# SPDX-License-Identifier: GPL-3.0-or-later
azp/posix/1
+destructive
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
index dadeb6269..2c9bc6bd6 100644
--- a/ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml
@@ -7,13 +7,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: 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:
@@ -34,29 +28,44 @@
- '"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']
+ when:
+ - 'ansible_os_family not in ["Alpine", "AIX"]'
+ - '"systemctl" not in shutdown_result["shutdown_command"]'
+ - '"systemctl" not in shutdown_result_minus["shutdown_command"]'
-- name: Verify shutdown command is present except Alpine, VMKernel
+- name: Verify shutdown command is present except Alpine or AIX or systemd
assert:
that: '"shutdown" in shutdown_result["shutdown_command"]'
- when: ansible_os_family != 'Alpine' and ansible_system != 'VMKernel'
+ when:
+ - "ansible_os_family != 'Alpine'"
+ - "ansible_system != 'VMKernel'"
+ - '"systemctl" not in shutdown_result["shutdown_command"]'
-- name: Verify shutdown command is present in Alpine
+- name: Verify shutdown command is present in Alpine except systemd
assert:
that: '"poweroff" in shutdown_result["shutdown_command"]'
- when: ansible_os_family == 'Alpine'
+ when:
+ - "ansible_os_family == 'Alpine'"
+ - '"systemctl" not in shutdown_result["shutdown_command"]'
-- name: Verify shutdown command is present in VMKernel
+
+- name: Verify shutdown command is present in VMKernel except systemd
assert:
that: '"halt" in shutdown_result["shutdown_command"]'
- when: ansible_system == 'VMKernel'
+ when:
+ - "ansible_system == 'VMKernel'"
+ - '"systemctl" not in shutdown_result["shutdown_command"]'
-- name: Verify shutdown delay is present in minutes in Linux
+- name: Verify shutdown delay is present in minutes in Linux except systemd
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'
+ when:
+ - "ansible_system == 'Linux'"
+ - "ansible_os_family != 'Alpine'"
+ - '"systemctl" not in shutdown_result["shutdown_command"]'
+ - '"systemctl" not in shutdown_result_minus["shutdown_command"]'
- name: Verify shutdown delay is present in minutes in Void, MacOSX, OpenBSD
assert:
@@ -68,8 +77,8 @@
- 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"]'
+ - '"-p +100s" in shutdown_result["shutdown_command"]'
+ - '"-p +0s" in shutdown_result_minus["shutdown_command"]'
when: ansible_system == 'FreeBSD'
- name: Verify shutdown delay is present in seconds in Solaris, SunOS
@@ -86,8 +95,30 @@
- '"-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
+- name: Ensure that systemd-sysv is absent in Ubuntu 18 and Debian
apt:
- name: systemd-sysv
+ name: sytemd-sysv
state: absent
- when: systemd_sysv_install is changed
+ when: (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18', '>=')) or (ansible_distribution == 'Debian')
+ register: systemd_sysv_install
+
+- name: Gather package facts
+ package_facts:
+ manager: apt
+ when: (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18', '>=')) or (ansible_distribution == 'Debian')
+
+- name: Execute shutdown if no systemd-sysv
+ community.general.shutdown:
+ register: shutdown_result
+ check_mode: true
+ when:
+ - "(ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18', '>=')) or (ansible_distribution == 'Debian')"
+ - '"systemd-sysv" not in ansible_facts.packages'
+
+- name: Install systemd_sysv in case it has been removed in test
+ apt:
+ name: systemd-sysv
+ state: present
+ when:
+ - "(ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18', '>=')) or (ansible_distribution == 'Debian')"
+ - "systemd_sysv_install is changed"
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
index f36427f71..5c4a48a41 100644
--- a/ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml
@@ -5,3 +5,4 @@
dependencies:
- setup_snap
+ - setup_remote_tmp_dir
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
index 0f24e69f3..2a683617a 100644
--- a/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
@@ -8,236 +8,18 @@
# GNU General Public License v3.0+ (see LICENSES/GPL-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
+- name: Has-snap include
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
+ - name: Include test
+ ansible.builtin.include_tasks: test.yml
+ # TODO: Find better package to install from a channel - microk8s installation takes multiple minutes, and even removal takes one minute!
+ # - name: Include test_channel
+ # ansible.builtin.include_tasks: test_channel.yml
+ # TODO: Find bettter package to download and install from sources - cider 1.6.0 takes over 35 seconds to install
+ # - name: Include test_dangerous
+ # ansible.builtin.include_tasks: test_dangerous.yml
+ - name: Include test_3dash
+ ansible.builtin.include_tasks: test_3dash.yml
+ - name: Include test_empty_list
+ ansible.builtin.include_tasks: test_empty_list.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test.yml
new file mode 100644
index 000000000..3a77704b3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test.yml
@@ -0,0 +1,235 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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 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/tasks/test_3dash.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_3dash.yml
new file mode 100644
index 000000000..4d39c0a48
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_3dash.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
+
+- name: Make sure packages are not installed (3 dashes)
+ community.general.snap:
+ name:
+ - bw
+ - shellcheck
+ state: absent
+
+- name: Install package with 3 dashes in description (check)
+ community.general.snap:
+ name:
+ - bw
+ - shellcheck
+ state: present
+ check_mode: true
+ register: install_3dash_check
+
+- name: Remove packages (3 dashes)
+ community.general.snap:
+ name:
+ - bw
+ - shellcheck
+ state: absent
+
+- assert:
+ that:
+ - install_3dash_check is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml
new file mode 100644
index 000000000..e9eb19c89
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.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
+
+# NOTE This is currently disabled for performance reasons!
+
+- name: Make sure package is not installed (microk8s)
+ community.general.snap:
+ name: microk8s
+ state: absent
+
+# Test for https://github.com/ansible-collections/community.general/issues/1606
+- name: Install package (microk8s)
+ community.general.snap:
+ name: microk8s
+ classic: true
+ state: present
+ register: install_microk8s
+
+- name: Install package with channel (microk8s)
+ community.general.snap:
+ name: microk8s
+ classic: true
+ channel: 1.20/stable
+ state: present
+ register: install_microk8s_chan
+
+- name: Install package with channel (microk8s) again
+ community.general.snap:
+ name: microk8s
+ classic: true
+ channel: 1.20/stable
+ state: present
+ register: install_microk8s_chan_again
+
+- name: Remove package (microk8s)
+ community.general.snap:
+ name: microk8s
+ state: absent
+ register: remove_microk8s
+
+- assert:
+ that:
+ - install_microk8s is changed
+ - install_microk8s_chan is changed
+ - install_microk8s_chan_again is not changed
+ - remove_microk8s is changed
+
+- name: Install package (shellcheck)
+ community.general.snap:
+ name: shellcheck
+ state: present
+ register: install_shellcheck
+
+- name: Install package with channel (shellcheck)
+ community.general.snap:
+ name: shellcheck
+ channel: edge
+ state: present
+ register: install_shellcheck_chan
+
+- name: Install package with channel (shellcheck) again
+ community.general.snap:
+ name: shellcheck
+ channel: edge
+ state: present
+ register: install_shellcheck_chan_again
+
+- name: Remove package (shellcheck)
+ community.general.snap:
+ name: shellcheck
+ state: absent
+ register: remove_shellcheck
+
+- assert:
+ that:
+ - install_shellcheck is changed
+ - install_shellcheck_chan is changed
+ - install_shellcheck_chan_again is not changed
+ - remove_shellcheck is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_dangerous.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_dangerous.yml
new file mode 100644
index 000000000..8fe4edee0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_dangerous.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
+
+# NOTE This is currently disabled for performance reasons!
+
+- name: Make sure package is not installed (cider)
+ community.general.snap:
+ name: cider
+ state: absent
+
+- name: Download cider snap
+ ansible.builtin.get_url:
+ url: https://github.com/ciderapp/cider-releases/releases/download/v1.6.0/cider_1.6.0_amd64.snap
+ dest: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
+ mode: "0644"
+
+# Test for https://github.com/ansible-collections/community.general/issues/5715
+- name: Install package from file (check)
+ community.general.snap:
+ name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
+ dangerous: true
+ state: present
+ check_mode: true
+ register: install_dangerous_check
+
+- name: Install package from file
+ community.general.snap:
+ name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
+ dangerous: true
+ state: present
+ register: install_dangerous
+
+- name: Install package from file
+ community.general.snap:
+ name: "{{ remote_tmp_dir }}/cider_1.6.0_amd64.snap"
+ dangerous: true
+ state: present
+ register: install_dangerous_idempot
+
+- name: Remove package
+ community.general.snap:
+ name: cider
+ state: absent
+ register: remove_dangerous
+
+- assert:
+ that:
+ - install_dangerous_check is changed
+ - install_dangerous is changed
+ - install_dangerous_idempot is not changed
+ - remove_dangerous is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_empty_list.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_empty_list.yml
new file mode 100644
index 000000000..bea73cb5e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/test_empty_list.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: Empty list present
+ community.general.snap:
+ name: []
+ state: present
+
+- name: Empty list absent
+ community.general.snap:
+ name: []
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases b/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases
index 6011128da..2c5cf3237 100644
--- a/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases
@@ -4,6 +4,5 @@
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/tasks/options.yml b/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml
index 406de6831..f88f99081 100644
--- 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
@@ -15,7 +15,12 @@
host: "options.example.com"
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add
check_mode: true
@@ -33,7 +38,7 @@
src: "{{ ssh_config_test }}"
register: slurp_ssh_config
-- name: "Options - Verify that nothign was added to {{ ssh_config_test }} during change mode"
+- name: "Options - Verify that nothing was added to {{ ssh_config_test }} during change mode"
assert:
that:
- "'options.example.com' not in slurp_ssh_config['content'] | b64decode"
@@ -44,7 +49,12 @@
host: "options.example.com"
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add
@@ -62,7 +72,12 @@
host: "options.example.com"
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add_again
@@ -84,7 +99,12 @@
that:
- "'proxycommand ssh jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent yes' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly yes' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster auto' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
- name: Options - Update host
community.general.ssh_config:
@@ -92,7 +112,12 @@
host: "options.example.com"
proxycommand: "ssh new-jumphost.example.com -W %h:%p"
forward_agent: false
+ add_keys_to_agent: false
host_key_algorithms: "+ssh-ed25519"
+ identities_only: false
+ controlmaster: no
+ controlpath: "~/.ssh/new-sockets/%r@%h-%p"
+ controlpersist: "600"
state: present
register: options_update
@@ -112,7 +137,12 @@
host: "options.example.com"
proxycommand: "ssh new-jumphost.example.com -W %h:%p"
forward_agent: false
+ add_keys_to_agent: false
host_key_algorithms: "+ssh-ed25519"
+ identities_only: false
+ controlmaster: no
+ controlpath: "~/.ssh/new-sockets/%r@%h-%p"
+ controlpersist: "600"
state: present
register: options_update
@@ -135,7 +165,12 @@
that:
- "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist 600' 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:
@@ -163,7 +198,12 @@
that:
- "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
- name: Debug
debug:
@@ -209,7 +249,12 @@
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"
+ - "'addkeystoagent no' not in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster auto' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
# Proxycommand and ProxyJump are mutually exclusive.
# Reset ssh_config before testing options with proxyjump
@@ -225,7 +270,12 @@
host: "options.example.com"
proxyjump: "jumphost.example.com"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add
check_mode: true
@@ -243,7 +293,7 @@
src: "{{ ssh_config_test }}"
register: slurp_ssh_config
-- name: "Options - Verify that nothign was added to {{ ssh_config_test }} during change mode"
+- name: "Options - Verify that nothing was added to {{ ssh_config_test }} during change mode"
assert:
that:
- "'options.example.com' not in slurp_ssh_config['content'] | b64decode"
@@ -254,7 +304,12 @@
host: "options.example.com"
proxyjump: "jumphost.example.com"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add
@@ -272,7 +327,12 @@
host: "options.example.com"
proxyjump: "jumphost.example.com"
forward_agent: true
+ add_keys_to_agent: true
host_key_algorithms: "+ssh-rsa"
+ identities_only: true
+ controlmaster: "auto"
+ controlpath: "~/.ssh/sockets/%r@%h-%p"
+ controlpersist: yes
state: present
register: options_add_again
@@ -294,7 +354,12 @@
that:
- "'proxyjump jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent yes' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly yes' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster auto' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
- name: Options - Update host
community.general.ssh_config:
@@ -302,7 +367,12 @@
host: "options.example.com"
proxyjump: "new-jumphost.example.com"
forward_agent: false
+ add_keys_to_agent: false
host_key_algorithms: "+ssh-ed25519"
+ identities_only: false
+ controlmaster: no
+ controlpath: "~/.ssh/new-sockets/%r@%h-%p"
+ controlpersist: "600"
state: present
register: options_update
@@ -322,7 +392,12 @@
host: "options.example.com"
proxyjump: "new-jumphost.example.com"
forward_agent: false
+ add_keys_to_agent: false
host_key_algorithms: "+ssh-ed25519"
+ identities_only: false
+ controlmaster: no
+ controlpath: "~/.ssh/new-sockets/%r@%h-%p"
+ controlpersist: "600"
state: present
register: options_update
@@ -345,7 +420,12 @@
that:
- "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist 600' 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:
@@ -373,7 +453,12 @@
that:
- "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster no' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
- name: Debug
debug:
@@ -419,4 +504,9 @@
that:
- "'proxyjump new-jumphost.example.com' not in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
+ - "'addkeystoagent no' not in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
+ - "'identitiesonly no' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlmaster auto' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
+ - "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
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
index dd62025d5..36397f41a 100644
--- a/ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml
@@ -159,6 +159,20 @@
src: "{{ sudoers_path }}/my-sudo-rule-8"
register: rule_8_contents
+- name: Create rule with noexec parameters
+ community.general.sudoers:
+ name: my-sudo-rule-9
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ noexec: true
+ register: rule_9
+
+- name: Grab contents of my-sudo-rule-9
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-9"
+ register: rule_9_contents
+
- name: Revoke rule 1
community.general.sudoers:
name: my-sudo-rule-1
@@ -257,6 +271,7 @@
- "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'"
+ - "rule_9_contents['content'] | b64decode == 'alice ALL=NOEXEC:NOPASSWD: /usr/local/bin/command\n'"
- name: Check revocation stat
ansible.builtin.assert:
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
index 2c45c3b1c..ace38202f 100644
--- a/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml
@@ -140,11 +140,11 @@
- 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
+ # NOTE: currently fails with FreeBSD 13 with minor version less than 2
#
when: >-
ansible_distribution_version is version('12.4', '>=') and ansible_distribution_version is version('13', '<')
- or ansible_distribution_version is version('13.1', '>=')
+ or ansible_distribution_version is version('13.2', '>=')
block:
- name: Setup testjail
include_tasks: setup-testjail.yml
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
index 1c66990be..d04757d8e 100644
--- a/ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml
@@ -63,5 +63,5 @@
loop_control:
index_var: provider_index
-- name: Test Complex Varibles
+- name: Test Complex Variables
ansible.builtin.include_tasks: complex_variables.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/aliases b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/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/test_fqdn_valid/runme.sh b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.sh
new file mode 100755
index 000000000..cd97ac949
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/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 fqdn
+
+ANSIBLE_ROLES_PATH=../ ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.yml b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.yml
new file mode 100644
index 000000000..37f965b28
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/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: test_fqdn_valid}
diff --git a/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/fqdn_valid_1.yml b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/fqdn_valid_1.yml
new file mode 100644
index 000000000..36cfffad0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/fqdn_valid_1.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: Debug ansible_version
+ ansible.builtin.debug:
+ var: ansible_version
+ when: debug_test|d(false)|bool
+ tags: t0
+
+- name: 1. Test valid hostnames. Default options.
+ block:
+ - name: "1. Default min_labels=1, allow_underscores=False"
+ ansible.builtin.debug:
+ msg: "hosts_invalid: {{ hosts_invalid }}"
+ when: debug_test|d(false)|bool
+ - name: Assert
+ ansible.builtin.assert:
+ that: hosts_invalid|difference(result)|length == 0
+ vars:
+ hosts_valid: "{{ names1|select('community.general.fqdn_valid') }}"
+ hosts_invalid: "{{ names1|difference(hosts_valid) }}"
+ result: [-rv.example.com, -rv, s_v]
+ tags: t1
+
+- name: 2. Test valid hostnames. allow_underscores=True
+ block:
+ - name: "2. allow_underscores=True, default min_labels=1"
+ ansible.builtin.debug:
+ msg: "hosts_invalid: {{ hosts_invalid }}"
+ when: debug_test|d(false)|bool
+ - name: Assert
+ ansible.builtin.assert:
+ that: hosts_invalid|difference(result)|length == 0
+ vars:
+ hosts_valid: "{{ names2|select('community.general.fqdn_valid',
+ allow_underscores=True) }}"
+ hosts_invalid: "{{ names2|difference(hosts_valid) }}"
+ result: [-rv]
+ tags: t2
+
+- name: 3. Test valid hostnames. min_labels=2, allow_underscores=True
+ block:
+ - name: "3. allow_underscores=True, min_labels=2"
+ ansible.builtin.debug:
+ msg: "hosts_invalid: {{ hosts_invalid }}"
+ when: debug_test|d(false)|bool
+ - name: Assert
+ ansible.builtin.assert:
+ that: hosts_invalid|difference(result)|length == 0
+ vars:
+ hosts_valid: "{{ names3|select('community.general.fqdn_valid',
+ min_labels=2,
+ allow_underscores=True) }}"
+ hosts_invalid: "{{ names3|difference(hosts_valid) }}"
+ result: [9rv, s_v-.x.y]
+ tags: t3
diff --git a/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/main.yml
new file mode 100644
index 000000000..3bb62555a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/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
+
+- name: Test fqdn_valid
+ ansible.builtin.import_tasks: fqdn_valid_1.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/vars/main.yml
new file mode 100644
index 000000000..ba0a0eb08
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/vars/main.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
+
+names1:
+ - srv.example.com
+ - 9rv.example.com
+ - -rv.example.com
+ - srv
+ - 9rv
+ - -rv
+ - s_v
+names2: [9rv, -rv, s_v]
+names3: [9rv, srv.x, s_v.x.y, s_v-.x.y]
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
index 3644eeafa..721341592 100644
--- a/ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml
@@ -77,6 +77,7 @@
when:
- ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['Fedora31', 'Fedora32']
- not (ansible_os_family == 'Alpine') # TODO
+ - not (ansible_distribution == 'Archlinux') # TODO
block:
- name: set timezone to Etc/UTC
timezone:
@@ -93,4 +94,4 @@
- name: Restore original system timezone - {{ original_timezone.diff.before.name }}
timezone:
name: "{{ original_timezone.diff.before.name }}"
- when: original_timezone is changed
+ when: original_timezone is changed and original_timezone.diff.before.name != 'n/a'
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/aliases b/ansible_collections/community/general/tests/integration/targets/ufw/aliases
index 2ef1a4133..209a1153e 100644
--- a/ansible_collections/community/general/tests/integration/targets/ufw/aliases
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/aliases
@@ -11,6 +11,8 @@ skip/freebsd
skip/rhel8.0 # FIXME
skip/rhel9.0 # FIXME
skip/rhel9.1 # FIXME
+skip/rhel9.2 # FIXME
+skip/rhel9.3 # FIXME
skip/docker
needs/root
needs/target/setup_epel
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
index fe46b3ae5..8235f1a6b 100644
--- a/ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml
@@ -14,6 +14,15 @@
state: present
when: ansible_os_family == "FreeBSD"
+- name: Install requirements (RHEL 8)
+ package:
+ name:
+ - libxml2-devel
+ - libxslt-devel
+ - python3-lxml
+ state: present
+ when: ansible_distribution == "RedHat" and ansible_distribution_major_version == "8"
+
# Needed for MacOSX !
- name: Install lxml
pip: