From 38b7c80217c4e72b1d8988eb1e60bb6e77334114 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 18 Apr 2024 07:52:22 +0200 Subject: Adding upstream version 9.4.0+dfsg. Signed-off-by: Daniel Baumann --- .../targets/aix_filesystem/tasks/main.yml | 2 +- .../alternatives/tasks/tests_set_priority.yml | 2 +- .../targets/ansible_galaxy_install/aliases | 1 - .../targets/apache2_module/tasks/actualtest.yml | 2 +- .../general/tests/integration/targets/apk/aliases | 13 + .../tests/integration/targets/apk/tasks/main.yml | 160 ++++++ .../integration/targets/archive/tests/core.yml | 10 +- .../integration/targets/archive/tests/remove.yml | 30 +- .../integration/targets/btrfs_subvolume/aliases | 2 +- .../targets/callback_default_without_diff/aliases | 6 + .../callback_default_without_diff/tasks/main.yml | 65 +++ .../tests/integration/targets/cargo/tasks/main.yml | 2 + .../integration/targets/cargo/tasks/setup.yml | 14 + .../targets/cargo/tasks/test_rustup_cargo.yml | 23 + .../targets/cloud_init_data_facts/tasks/main.yml | 11 +- .../cmd_runner/action_plugins/_unsafe_assert.py | 56 ++ .../targets/cmd_runner/library/cmd_echo.py | 5 +- .../integration/targets/cmd_runner/meta/main.yml | 7 + .../integration/targets/cmd_runner/tasks/main.yml | 1 + .../targets/cmd_runner/tasks/test_cmd_echo.yml | 28 +- .../integration/targets/cmd_runner/vars/main.yml | 139 +++++ .../integration/targets/connection_incus/aliases | 6 + .../integration/targets/connection_incus/runme.sh | 21 + .../connection_incus/test_connection.inventory | 11 + .../targets/consul/tasks/consul_auth_method.yml | 74 +++ .../targets/consul/tasks/consul_binding_rule.yml | 73 +++ .../targets/consul/tasks/consul_general.yml | 76 +++ .../integration/targets/consul/tasks/consul_kv.yml | 57 ++ .../targets/consul/tasks/consul_policy.yml | 72 +++ .../targets/consul/tasks/consul_role.yml | 194 +++++++ .../targets/consul/tasks/consul_session.yml | 57 +- .../targets/consul/tasks/consul_token.yml | 88 +++ .../integration/targets/consul/tasks/main.yml | 28 +- .../targets/consul/templates/consul_config.hcl.j2 | 5 + .../tests/integration/targets/copr/tasks/main.yml | 6 - .../targets/deploy_helper/tasks/main.yml | 18 +- .../integration/targets/django_manage/aliases | 5 + .../integration/targets/ejabberd_user/aliases | 11 + .../targets/ejabberd_user/handlers/main.yml | 9 + .../targets/ejabberd_user/meta/main.yml | 7 + .../targets/ejabberd_user/tasks/main.yml | 122 +++++ .../tests/integration/targets/etcd3/aliases | 1 - .../integration/targets/filesize/tasks/sparse.yml | 122 ++--- .../targets/filesystem/defaults/main.yml | 28 +- .../integration/targets/filesystem/tasks/main.yml | 3 +- .../targets/filesystem/tasks/reset_fs_uuid.yml | 59 ++ .../filesystem/tasks/set_fs_uuid_on_creation.yml | 44 ++ .../tasks/set_fs_uuid_on_creation_with_opts.yml | 33 ++ .../integration/targets/filter_counter/aliases | 1 - .../tests/integration/targets/filter_dict/aliases | 1 - .../integration/targets/filter_dict_kv/aliases | 1 - .../integration/targets/filter_from_csv/aliases | 1 - .../targets/filter_from_ini/tasks/main.yml | 60 ++ .../targets/filter_from_ini/vars/main.yml | 8 + .../targets/filter_groupby_as_dict/aliases | 1 - .../integration/targets/filter_hashids/aliases | 1 - .../tests/integration/targets/filter_jc/aliases | 3 +- .../integration/targets/filter_json_query/aliases | 1 - .../tests/integration/targets/filter_lists/aliases | 5 + .../targets/filter_lists/tasks/main.yml | 64 +++ .../integration/targets/filter_lists/vars/main.yml | 8 + .../targets/filter_lists_mergeby/aliases | 1 - .../targets/filter_path_join_shim/aliases | 1 - .../integration/targets/filter_random_mac/aliases | 1 - .../tests/integration/targets/filter_time/aliases | 1 - .../targets/filter_to_ini/tasks/main.yml | 58 ++ .../targets/filter_to_ini/vars/main.yml | 8 + .../targets/filter_unicode_normalize/aliases | 1 - .../targets/filter_version_sort/aliases | 1 - .../tests/integration/targets/gem/tasks/main.yml | 2 +- .../integration/targets/git_config/files/gitconfig | 5 + .../tasks/get_set_state_present_file.yml | 1 + .../integration/targets/git_config/tasks/main.yml | 3 + .../targets/git_config/tasks/set_multi_value.yml | 79 +++ .../targets/git_config/tasks/set_value.yml | 39 ++ .../git_config/tasks/set_value_with_tilde.yml | 4 +- .../targets/git_config/tasks/unset_multi_value.yml | 28 + .../integration/targets/git_config_info/aliases | 7 + .../targets/git_config_info/files/gitconfig | 11 + .../targets/git_config_info/meta/main.yml | 7 + .../git_config_info/tasks/error_handling.yml | 26 + .../git_config_info/tasks/get_all_values.yml | 19 + .../git_config_info/tasks/get_multi_value.yml | 20 + .../git_config_info/tasks/get_simple_value.yml | 38 ++ .../targets/git_config_info/tasks/main.yml | 33 ++ .../targets/git_config_info/tasks/setup.yml | 15 + .../targets/git_config_info/tasks/setup_file.yml | 16 + .../targets/git_config_info/tasks/setup_global.yml | 16 + .../targets/git_config_info/vars/main.yml | 7 + .../targets/gitlab_group_access_token/aliases | 7 + .../gitlab_group_access_token/defaults/main.yml | 15 + .../gitlab_group_access_token/tasks/main.yml | 221 ++++++++ .../targets/gitlab_instance_variable/aliases | 5 + .../gitlab_instance_variable/tasks/main.yml | 606 +++++++++++++++++++++ .../tests/integration/targets/gitlab_issue/aliases | 6 + .../targets/gitlab_issue/defaults/main.yml | 15 + .../targets/gitlab_issue/files/description.md | 9 + .../targets/gitlab_issue/tasks/main.yml | 150 +++++ .../integration/targets/gitlab_label/README.md | 19 + .../tests/integration/targets/gitlab_label/aliases | 6 + .../targets/gitlab_label/defaults/main.yml | 17 + .../targets/gitlab_label/tasks/main.yml | 463 ++++++++++++++++ .../targets/gitlab_merge_request/aliases | 6 + .../targets/gitlab_merge_request/defaults/main.yml | 14 + .../gitlab_merge_request/files/description.md | 9 + .../targets/gitlab_merge_request/tasks/main.yml | 129 +++++ .../integration/targets/gitlab_milestone/README.md | 19 + .../integration/targets/gitlab_milestone/aliases | 6 + .../targets/gitlab_milestone/defaults/main.yml | 18 + .../targets/gitlab_milestone/tasks/main.yml | 388 +++++++++++++ .../targets/gitlab_project_access_token/aliases | 7 + .../gitlab_project_access_token/defaults/main.yml | 15 + .../gitlab_project_access_token/tasks/main.yml | 221 ++++++++ .../tests/integration/targets/homebrew/aliases | 1 - .../integration/targets/homebrew/tasks/casks.yml | 99 ++++ .../targets/homebrew/tasks/formulae.yml | 99 ++++ .../integration/targets/homebrew/tasks/main.yml | 92 +--- .../integration/targets/homebrew_cask/aliases | 1 - .../tests/integration/targets/homectl/aliases | 2 + .../tests/integration/targets/htpasswd/aliases | 7 + .../integration/targets/htpasswd/handlers/main.yml | 9 + .../integration/targets/htpasswd/meta/main.yml | 7 + .../integration/targets/htpasswd/tasks/main.yml | 83 +++ .../integration/targets/htpasswd/vars/main.yml | 6 + .../integration/targets/ini_file/tasks/main.yml | 12 + .../targets/ini_file/tasks/tests/00-basic.yml | 4 +- .../targets/ini_file/tasks/tests/04-symlink.yml | 59 ++ .../ini_file/tasks/tests/05-ignore_spaces.yml | 123 +++++ .../tasks/tests/06-modify_inactive_option.yml | 123 +++++ .../tasks/tests/07-section_name_spaces.yml | 103 ++++ .../targets/interfaces_file/tasks/main.yml | 58 ++ .../targets/iptables_state/tasks/main.yml | 6 + .../tasks/tests/02-partial-restore.yml | 66 +++ .../tests/integration/targets/iso_create/aliases | 1 - .../integration/targets/iso_customize/aliases | 1 - .../tasks/iso_customize_exception.yml | 2 +- .../tests/integration/targets/iso_extract/aliases | 4 + .../tests/integration/targets/java_cert/aliases | 1 + .../targets/java_cert/files/setupSSLServer.py | 13 +- .../targets/java_cert/tasks/state_change.yml | 2 +- .../integration/targets/java_keystore/aliases | 1 + .../integration/targets/kernel_blacklist/aliases | 4 + .../targets/kernel_blacklist/handlers/main.yml | 10 + .../targets/kernel_blacklist/tasks/main.yml | 72 ++- .../keycloak_authz_authorization_scope/readme.adoc | 2 +- .../targets/keycloak_authz_custom_policy/aliases | 5 + .../policy/Containerfile | 4 + .../policy/Containerfile.license | 3 + .../policy/META-INF/keycloak-scripts.json | 14 + .../policy/META-INF/keycloak-scripts.json.license | 3 + .../policy/build-policy.sh | 2 + .../policy/build-policy.sh.license | 3 + .../policy/policy-1.js | 1 + .../policy/policy-1.js.license | 3 + .../policy/policy-2.js | 1 + .../policy/policy-2.js.license | 3 + .../keycloak_authz_custom_policy/readme.adoc | 27 + .../keycloak_authz_custom_policy/tasks/main.yml | 168 ++++++ .../keycloak_authz_custom_policy/vars/main.yml | 11 + .../targets/keycloak_authz_permission/aliases | 6 + .../targets/keycloak_authz_permission/readme.adoc | 27 + .../keycloak_authz_permission/tasks/main.yml | 567 +++++++++++++++++++ .../keycloak_authz_permission/vars/main.yml | 11 + .../integration/targets/keycloak_client/README.md | 20 +- .../targets/keycloak_client/docker-compose.yml | 31 -- .../targets/keycloak_client/tasks/main.yml | 120 ++-- .../targets/keycloak_client/vars/main.yml | 2 +- .../targets/keycloak_component_info/README.md | 20 + .../targets/keycloak_component_info/aliases | 5 + .../targets/keycloak_component_info/tasks/main.yml | 266 +++++++++ .../targets/keycloak_component_info/vars/main.yml | 19 + .../integration/targets/keycloak_group/readme.adoc | 2 +- .../targets/keycloak_group_rolemapping/README.md | 21 + .../targets/keycloak_group_rolemapping/aliases | 4 + .../keycloak_group_rolemapping/tasks/main.yml | 160 ++++++ .../keycloak_group_rolemapping/vars/main.yml | 15 + .../keycloak_identity_provider/tasks/main.yml | 113 +++- .../integration/targets/keycloak_realm_key/aliases | 5 + .../targets/keycloak_realm_key/readme.adoc | 27 + .../targets/keycloak_realm_key/tasks/main.yml | 373 +++++++++++++ .../targets/keycloak_realm_key/vars/main.yml | 48 ++ .../integration/targets/keycloak_role/README.md | 20 + .../targets/keycloak_role/tasks/main.yml | 233 ++++++++ .../targets/keycloak_role/vars/main.yml | 27 + .../integration/targets/keycloak_user/README.md | 21 + .../integration/targets/keycloak_user/aliases | 4 + .../targets/keycloak_user/tasks/main.yml | 114 ++++ .../targets/keycloak_user/vars/main.yml | 46 ++ .../targets/ldap_search/tasks/tests/auth.yml | 47 ++ .../targets/ldap_search/tasks/tests/basic.yml | 14 + .../targets/ldap_search/tasks/tests/pages.yml | 24 + .../targets/ldap_search/tasks/tests/schema.yml | 25 + .../targets/listen_ports_facts/tasks/main.yml | 2 +- .../tests/integration/targets/locale_gen/aliases | 2 + .../integration/targets/locale_gen/tasks/basic.yml | 102 ++++ .../targets/locale_gen/tasks/locale_gen.yml | 99 ---- .../integration/targets/locale_gen/tasks/main.yml | 10 +- .../integration/targets/locale_gen/vars/main.yml | 17 + .../integration/targets/lookup_cartesian/aliases | 1 - .../integration/targets/lookup_dependent/aliases | 1 - .../tests/integration/targets/lookup_dig/aliases | 1 - .../tests/integration/targets/lookup_etcd3/aliases | 1 - .../integration/targets/lookup_flattened/aliases | 1 - .../integration/targets/lookup_lmdb_kv/aliases | 1 - .../targets/lookup_merge_variables/aliases | 1 - .../targets/lookup_merge_variables/runme.sh | 3 + .../lookup_merge_variables/test_all_hosts.yml | 64 +++ .../test_inventory_all_hosts.yml | 52 ++ .../targets/lookup_passwordstore/aliases | 1 - .../integration/targets/lookup_random_pet/aliases | 1 - .../targets/lookup_random_string/aliases | 1 - .../targets/lookup_random_words/aliases | 1 - .../tests/integration/targets/lvg/tasks/main.yml | 10 + .../tests/integration/targets/lvg/tasks/setup.yml | 20 +- .../targets/lvg/tasks/setup_missing_pv.yml | 18 + .../integration/targets/lvg/tasks/teardown.yml | 14 +- .../targets/lvg/tasks/teardown_missing_pv.yml | 8 + .../targets/lvg/tasks/test_active_change.yml | 163 ++++++ .../targets/lvg/tasks/test_active_create.yml | 71 +++ .../targets/lvg/tasks/test_pvresize.yml | 16 +- .../targets/lvg/tasks/test_uuid_reset.yml | 107 ++++ .../tests/integration/targets/lvg_rename/aliases | 13 + .../integration/targets/lvg_rename/meta/main.yml | 9 + .../integration/targets/lvg_rename/tasks/main.yml | 25 + .../integration/targets/lvg_rename/tasks/setup.yml | 50 ++ .../targets/lvg_rename/tasks/teardown.yml | 46 ++ .../integration/targets/lvg_rename/tasks/test.yml | 105 ++++ .../general/tests/integration/targets/lvol/aliases | 12 + .../tests/integration/targets/lvol/meta/main.yml | 8 + .../tests/integration/targets/lvol/tasks/main.yml | 24 + .../tests/integration/targets/lvol/tasks/setup.yml | 57 ++ .../integration/targets/lvol/tasks/teardown.yml | 40 ++ .../integration/targets/lvol/tasks/test_pvs.yml | 64 +++ .../tests/integration/targets/mail/tasks/main.yml | 171 +++--- .../tests/integration/targets/mas/tasks/main.yml | 2 +- .../tests/integration/targets/monit/aliases | 1 - .../targets/mssql_script/tasks/main.yml | 37 ++ .../tests/integration/targets/nomad/aliases | 1 + .../tests/integration/targets/npm/tasks/test.yml | 13 +- .../general/tests/integration/targets/odbc/aliases | 2 + .../tests/integration/targets/odbc/tasks/main.yml | 1 + .../integration/targets/one_host/tasks/main.yml | 2 +- .../targets/osx_defaults/tasks/main.yml | 6 +- .../integration/targets/pacman/handlers/main.yml | 23 + .../pacman/tasks/locally_installed_package.yml | 3 +- .../integration/targets/pacman/tasks/main.yml | 1 + .../targets/pacman/tasks/remove_nosave.yml | 6 +- .../targets/pacman/tasks/yay-become.yml | 66 +++ .../tests/integration/targets/pids/tasks/main.yml | 2 +- .../targets/pids/templates/obtainpid.sh | 7 - .../targets/pids/templates/obtainpid.sh.j2 | 7 + .../general/tests/integration/targets/pipx/aliases | 1 + .../tests/integration/targets/pipx/tasks/main.yml | 25 + .../tests/integration/targets/pipx_info/aliases | 1 + .../integration/targets/pkgng/tasks/freebsd.yml | 9 +- .../general/tests/integration/targets/pnpm/aliases | 8 + .../tests/integration/targets/pnpm/meta/main.yml | 9 + .../tests/integration/targets/pnpm/tasks/main.yml | 27 + .../tests/integration/targets/pnpm/tasks/run.yml | 322 +++++++++++ .../integration/targets/pnpm/templates/package.j2 | 13 + .../integration/targets/proxmox/tasks/main.yml | 36 ++ .../tests/integration/targets/proxmox_pool/aliases | 7 + .../targets/proxmox_pool/defaults/main.yml | 7 + .../targets/proxmox_pool/tasks/main.yml | 220 ++++++++ .../integration/targets/proxmox_template/aliases | 6 + .../targets/proxmox_template/tasks/main.yml | 136 +++++ .../targets/scaleway_compute/tasks/pagination.yml | 4 +- .../scaleway_container_registry/tasks/main.yml | 2 +- .../targets/scaleway_image_info/tasks/main.yml | 4 +- .../targets/scaleway_ip_info/tasks/main.yml | 4 +- .../scaleway_organization_info/tasks/main.yml | 2 +- .../scaleway_security_group_info/tasks/main.yml | 4 +- .../targets/scaleway_server_info/tasks/main.yml | 4 +- .../targets/scaleway_snapshot_info/tasks/main.yml | 4 +- .../targets/scaleway_volume_info/tasks/main.yml | 4 +- .../targets/setup_docker/handlers/main.yml | 18 +- .../targets/setup_docker/tasks/main.yml | 2 + .../integration/targets/setup_etcd3/tasks/main.yml | 2 +- .../targets/setup_java_keytool/tasks/main.yml | 12 +- .../targets/setup_java_keytool/vars/Alpine.yml | 3 +- .../targets/setup_java_keytool/vars/Archlinux.yml | 3 +- .../targets/setup_java_keytool/vars/Debian-12.yml | 8 + .../targets/setup_java_keytool/vars/Debian.yml | 3 +- .../targets/setup_java_keytool/vars/RedHat.yml | 3 +- .../targets/setup_java_keytool/vars/Suse.yml | 3 +- .../setup_openldap/files/cert_cnconfig.ldif | 15 + .../files/cert_cnconfig.ldif.license | 3 + .../setup_openldap/files/initial_config.ldif | 19 + .../targets/setup_openldap/tasks/main.yml | 22 +- .../targets/setup_pkg_mgr/tasks/archlinux.yml | 5 + .../targets/setup_postgresql_db/tasks/main.yml | 26 + .../setup_postgresql_db/vars/Debian-12-py3.yml | 13 + .../targets/setup_snap/tasks/D-RedHat-9.2.yml | 6 + .../targets/setup_snap/tasks/D-RedHat-9.3.yml | 6 + .../targets/setup_tls/files/ca_certificate.pem | 4 - .../setup_tls/files/ca_certificate.pem.license | 3 + .../integration/targets/setup_tls/files/ca_key.pem | 4 - .../targets/setup_tls/files/ca_key.pem.license | 3 + .../targets/setup_tls/files/client_certificate.pem | 4 - .../setup_tls/files/client_certificate.pem.license | 3 + .../targets/setup_tls/files/client_key.pem | 4 - .../targets/setup_tls/files/client_key.pem.license | 3 + .../targets/setup_tls/files/server_certificate.pem | 4 - .../setup_tls/files/server_certificate.pem.license | 3 + .../targets/setup_tls/files/server_key.pem | 4 - .../targets/setup_tls/files/server_key.pem.license | 3 + .../tests/integration/targets/shutdown/aliases | 1 + .../integration/targets/shutdown/tasks/main.yml | 73 ++- .../tests/integration/targets/snap/meta/main.yml | 1 + .../tests/integration/targets/snap/tasks/main.yml | 244 +-------- .../tests/integration/targets/snap/tasks/test.yml | 235 ++++++++ .../integration/targets/snap/tasks/test_3dash.yml | 31 ++ .../targets/snap/tasks/test_channel.yml | 81 +++ .../targets/snap/tasks/test_dangerous.yml | 53 ++ .../targets/snap/tasks/test_empty_list.yml | 14 + .../tests/integration/targets/ssh_config/aliases | 1 - .../targets/ssh_config/tasks/options.yml | 94 +++- .../integration/targets/sudoers/tasks/main.yml | 15 + .../tests/integration/targets/sysrc/tasks/main.yml | 4 +- .../integration/targets/terraform/tasks/main.yml | 2 +- .../integration/targets/test_fqdn_valid/aliases | 5 + .../integration/targets/test_fqdn_valid/runme.sh | 15 + .../integration/targets/test_fqdn_valid/runme.yml | 8 + .../targets/test_fqdn_valid/tasks/fqdn_valid_1.yml | 58 ++ .../targets/test_fqdn_valid/tasks/main.yml | 7 + .../targets/test_fqdn_valid/vars/main.yml | 15 + .../integration/targets/timezone/tasks/main.yml | 3 +- .../general/tests/integration/targets/ufw/aliases | 2 + .../tests/integration/targets/xml/tasks/main.yml | 9 + 329 files changed, 11233 insertions(+), 945 deletions(-) create mode 100644 ansible_collections/community/general/tests/integration/targets/apk/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/apk/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/callback_default_without_diff/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_rustup_cargo.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/cmd_runner/action_plugins/_unsafe_assert.py create mode 100644 ansible_collections/community/general/tests/integration/targets/cmd_runner/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/connection_incus/aliases create mode 100755 ansible_collections/community/general/tests/integration/targets/connection_incus/runme.sh create mode 100644 ansible_collections/community/general/tests/integration/targets/connection_incus/test_connection.inventory create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_auth_method.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_binding_rule.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_general.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_kv.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_policy.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_role.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_token.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ejabberd_user/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/ejabberd_user/handlers/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ejabberd_user/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ejabberd_user/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filesystem/tasks/reset_fs_uuid.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filesystem/tasks/set_fs_uuid_on_creation_with_opts.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_from_ini/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_lists/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_lists/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_lists/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/filter_to_ini/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_multi_value.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_multi_value.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/files/gitconfig create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/error_handling.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_all_values.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_multi_value.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/get_simple_value.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_file.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/tasks/setup_global.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/git_config_info/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_group_access_token/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_instance_variable/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_issue/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_issue/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_issue/files/description.md create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_issue/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_label/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_label/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_label/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_label/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/files/description.md create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_merge_request/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_milestone/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_milestone/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_milestone/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_milestone/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/gitlab_project_access_token/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/homebrew/tasks/casks.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/homebrew/tasks/formulae.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/htpasswd/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/htpasswd/handlers/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/htpasswd/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/htpasswd/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/htpasswd/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/04-symlink.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/05-ignore_spaces.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/06-modify_inactive_option.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/07-section_name_spaces.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/02-partial-restore.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/kernel_blacklist/handlers/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/Containerfile.license create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/META-INF/keycloak-scripts.json.license create mode 100755 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/build-policy.sh.license create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-1.js.license create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/policy/policy-2.js.license create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/readme.adoc create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_custom_policy/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/readme.adoc create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_authz_permission/vars/main.yml delete mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_component_info/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_component_info/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_component_info/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_component_info/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_group_rolemapping/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/readme.adoc create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_realm_key/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_role/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_user/README.md create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_user/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_user/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/keycloak_user/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/auth.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/pages.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/schema.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/basic.yml delete mode 100644 ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/locale_gen/vars/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_all_hosts.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_inventory_all_hosts.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup_missing_pv.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown_missing_pv.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_change.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_active_create.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_uuid_reset.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/setup.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/teardown.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvg_rename/tasks/test.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/tasks/setup.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/tasks/teardown.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/lvol/tasks/test_pvs.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/pacman/handlers/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/pacman/tasks/yay-become.yml delete mode 100644 ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh create mode 100644 ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2 create mode 100644 ansible_collections/community/general/tests/integration/targets/pnpm/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/pnpm/meta/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/pnpm/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/pnpm/tasks/run.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/pnpm/templates/package.j2 create mode 100644 ansible_collections/community/general/tests/integration/targets/proxmox_pool/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/proxmox_pool/defaults/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/proxmox_pool/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/proxmox_template/aliases create mode 100644 ansible_collections/community/general/tests/integration/targets/proxmox_template/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian-12.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_openldap/files/cert_cnconfig.ldif.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-12-py3.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.2.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.3.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem.license create mode 100644 ansible_collections/community/general/tests/integration/targets/snap/tasks/test.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/snap/tasks/test_3dash.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/snap/tasks/test_channel.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/snap/tasks/test_dangerous.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/snap/tasks/test_empty_list.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/aliases create mode 100755 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.sh create mode 100644 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/runme.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/fqdn_valid_1.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/tasks/main.yml create mode 100644 ansible_collections/community/general/tests/integration/targets/test_fqdn_valid/vars/main.yml (limited to 'ansible_collections/community/general/tests/integration') 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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/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 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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/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 +# GNU General Public License v3.0+ (see LICENSES/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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 @@ + + +### 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 @@ + + +# 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 --name --network=host --volume /ansible_community/community.general:/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 /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 /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 @@ + + +### 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 @@ + + +# 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 --name --network=host --volume /ansible_community/community.general:/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 /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 /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 +# GNU General Public License v3.0+ (see LICENSES/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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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= -e KEYCLOAK_ADMIN= -e KEYCLOAK_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 @@ + +# 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 @@ + + +# `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= -e KEYCLOAK_ADMIN= -e KEYCLOAK_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 @@ + +# 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 @@ + +# 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 deleted file mode 100644 index ecbf56aab..000000000 --- a/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) Ansible Project -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -"{{ remote_tmp_dir }}/{{ random_name }}" 100 & -echo "$!" > "{{ remote_tmp_dir }}/obtainpid.txt" diff --git a/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2 b/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2 new file mode 100644 index 000000000..ecbf56aab --- /dev/null +++ b/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh.j2 @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +"{{ remote_tmp_dir }}/{{ random_name }}" 100 & +echo "$!" > "{{ remote_tmp_dir }}/obtainpid.txt" diff --git a/ansible_collections/community/general/tests/integration/targets/pipx/aliases b/ansible_collections/community/general/tests/integration/targets/pipx/aliases 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 +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/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 +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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 +# GNU General Public License v3.0+ (see LICENSES/GPL-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: -- cgit v1.2.3