summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/general/tests')
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml1
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_ini/tasks/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_to_ini/tasks/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml98
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml159
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml341
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml317
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml4
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.18.txt17
-rw-r--r--ansible_collections/community/general/tests/sanity/ignore-2.18.txt.license3
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py14
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py12
-rw-r--r--ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py86
19 files changed, 1110 insertions, 29 deletions
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 ec446d241..7ff30bcd5 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
@@ -15,6 +15,7 @@ tested_filesystems:
# - 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
+ bcachefs: {fssize: 20, grow: true, new_uuid: null}
ext4: {fssize: 10, grow: true, new_uuid: 'random'}
ext4dev: {fssize: 10, grow: true, new_uuid: 'random'}
ext3: {fssize: 10, grow: true, new_uuid: 'random'}
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 0c15c2155..51361079c 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
@@ -36,7 +36,7 @@
# Not available: btrfs, lvm, f2fs, ocfs2
# All BSD systems use swap fs, but only Linux needs mkswap
# Supported: ext2/3/4 (e2fsprogs), xfs (xfsprogs), reiserfs (progsreiserfs), vfat
- - 'not (ansible_system == "FreeBSD" and item.0.key in ["btrfs", "f2fs", "swap", "lvm", "ocfs2"])'
+ - 'not (ansible_system == "FreeBSD" and item.0.key in ["bcachefs", "btrfs", "f2fs", "swap", "lvm", "ocfs2"])'
# Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix
- 'not (ansible_system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])'
@@ -46,6 +46,10 @@
# Other limitations and corner cases
+ # bcachefs only on Alpine > 3.18 and Arch Linux for now
+ # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests)
+ - 'ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">") and item.0.key == "bcachefs"'
+ - 'ansible_distribution == "Archlinux" and item.0.key == "bcachefs"'
# f2fs-tools and reiserfs-utils packages not available with RHEL/CentOS on CI
- 'not (ansible_distribution in ["CentOS", "RedHat"] and item.0.key in ["f2fs", "reiserfs"])'
- 'not (ansible_os_family == "RedHat" and ansible_distribution_major_version is version("8", ">=") and
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml
index 97dafaeee..77c028aca 100644
--- a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml
@@ -16,6 +16,16 @@
- e2fsprogs
- xfsprogs
+- name: "Install bcachefs tools"
+ ansible.builtin.package:
+ name: bcachefs-tools
+ state: present
+ when:
+ # bcachefs only on Alpine > 3.18 and Arch Linux for now
+ # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests)
+ - ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">")
+ - ansible_distribution == "Archlinux"
+
- name: "Install btrfs progs"
ansible.builtin.package:
name: btrfs-progs
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
index a2eca36a6..abb92dfc5 100644
--- 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
@@ -12,15 +12,21 @@
another_section:
connection: 'ssh'
+ interpolate_test:
+ interpolate_test_key: '%'
+
- 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
+ key_name = key value
[another_section]
- connection=ssh
+ connection = ssh
+
+ [interpolate_test]
+ interpolate_test_key = %
- name: 'Slurp the test file: {{ ini_test_file }}'
ansible.builtin.slurp:
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
index 877d4471d..e16aa98a5 100644
--- 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
@@ -16,6 +16,9 @@
another_section:
connection: 'ssh'
+ interpolate_test:
+ interpolate_test_key: '%'
+
- name: 'Write INI file manually to {{ ini_test_file }}'
ansible.builtin.copy:
dest: '{{ ini_test_file }}'
@@ -26,6 +29,9 @@
[another_section]
connection = ssh
+ [interpolate_test]
+ interpolate_test_key = %
+
- name: 'Slurp the manually created test file: {{ ini_test_file }}'
ansible.builtin.slurp:
src: '{{ ini_test_file }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml
index 9f52dc122..b4538200f 100644
--- a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml
@@ -52,6 +52,38 @@
- removal_result is not changed
msg: "Removing an absent flatpak shall mark module execution as not changed"
+# state=latest on absent flatpak
+
+- name: Test state=latest of absent flatpak (check mode)
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: latest
+ register: latest_result
+ check_mode: true
+
+- name: Verify state=latest of absent flatpak test result (check mode)
+ assert:
+ that:
+ - latest_result is changed
+ msg: "state=latest an absent flatpak shall mark module execution as changed"
+
+- name: Test non-existent idempotency of state=latest of absent flatpak (check mode)
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: latest
+ register: double_latest_result
+ check_mode: true
+
+- name: Verify non-existent idempotency of state=latest of absent flatpak test result (check mode)
+ assert:
+ that:
+ - double_latest_result is changed
+ msg: |
+ state=latest an absent flatpak a second time shall still mark module execution
+ as changed in check mode
+
# state=present with url on absent flatpak
- name: Test addition of absent flatpak with url (check mode)
@@ -101,6 +133,40 @@
- url_removal_result is not changed
msg: "Removing an absent flatpak shall mark module execution as not changed"
+# state=latest with url on absent flatpak
+
+- name: Test state=latest of absent flatpak with url (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: latest
+ register: url_latest_result
+ check_mode: true
+
+- name: Verify state=latest of absent flatpak with url test result (check mode)
+ assert:
+ that:
+ - url_latest_result is changed
+ msg: "state=latest an absent flatpak from URL shall mark module execution as changed"
+
+- name: Test non-existent idempotency of state=latest of absent flatpak with url (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: latest
+ register: double_url_latest_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of additionof state=latest flatpak with url test
+ result (check mode)
+ assert:
+ that:
+ - double_url_latest_result is changed
+ msg: |
+ state=latest an absent flatpak from URL a second time shall still mark module execution
+ as changed in check mode
+
# - Tests with present flatpak -------------------------------------------------
# state=present on present flatpak
@@ -149,6 +215,22 @@
Removing a present flatpak a second time shall still mark module execution
as changed in check mode
+# state=latest on present flatpak
+
+- name: Test state=latest of present flatpak (check mode)
+ flatpak:
+ name: com.dummy.App2
+ remote: dummy-remote
+ state: latest
+ register: latest_present_result
+ check_mode: true
+
+- name: Verify latest test result of present flatpak (check mode)
+ assert:
+ that:
+ - latest_present_result is changed
+ msg: "state=latest an present flatpak shall mark module execution as changed"
+
# state=present with url on present flatpak
- name: Test addition with url of present flatpak (check mode)
@@ -195,3 +277,19 @@
that:
- double_url_removal_present_result is changed
msg: Removing an absent flatpak a second time shall still mark module execution as changed
+
+# state=latest with url on present flatpak
+
+- name: Test state=latest with url of present flatpak (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: latest
+ register: url_latest_present_result
+ check_mode: true
+
+- name: Verify state=latest with url of present flatpak test result (check mode)
+ assert:
+ that:
+ - url_latest_present_result is changed
+ msg: "state=latest a present flatpak from URL shall mark module execution as changed"
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml
index 29c4efbe9..658f7b116 100644
--- a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml
@@ -65,6 +65,45 @@
- double_removal_result is not changed
msg: "state=absent shall not do anything when flatpak is not present"
+# state=latest
+
+- name: Test state=latest - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: latest_result
+
+- name: Verify state=latest test result - {{ method }}
+ assert:
+ that:
+ - latest_result is changed
+ msg: "state=latest shall add flatpak when absent"
+
+- name: Test idempotency of state=latest - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_latest_result
+
+- name: Verify idempotency of state=latest test result - {{ method }}
+ assert:
+ that:
+ - double_latest_result is not changed
+ msg: "state=latest shall not do anything when flatpak is already present"
+
+- name: Cleanup after state=present test - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+
# state=present with url as name
- name: Test addition with url - {{ method }}
@@ -152,6 +191,45 @@
method: "{{ method }}"
no_dependencies: true
+# state=latest with url as name
+
+- name: Test state=latest with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: url_latest_result
+
+- name: Verify state=latest test result - {{ method }}
+ assert:
+ that:
+ - url_latest_result is changed
+ msg: "state=present with url as name shall add flatpak when absent"
+
+- name: Test idempotency of state=latest with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_url_latest_result
+
+- name: Verify idempotency of state=latest with url test result - {{ method }}
+ assert:
+ that:
+ - double_url_latest_result is not changed
+ msg: "state=present with url as name shall not do anything when flatpak is already present"
+
+- name: Cleanup after state=present with url test - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+
# state=present with list of packages
- name: Test addition with list - {{ method }}
@@ -287,3 +365,84 @@
that:
- double_removal_result is not changed
msg: "state=absent shall not do anything when flatpak is not present"
+
+# state=latest with list of packages
+
+- name: Test state=latest with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: latest_result
+
+- name: Verify state=latest with list test result - {{ method }}
+ assert:
+ that:
+ - latest_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of state=latest with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_latest_result
+
+- name: Verify idempotency of state=latest with list test result - {{ method }}
+ assert:
+ that:
+ - double_latest_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+- name: Test state=latest with list partially installed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ - com.dummy.App3
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: latest_result
+
+- name: Verify state=latest with list partially installed test result - {{ method }}
+ assert:
+ that:
+ - latest_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of state=latest with list partially installed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ - com.dummy.App3
+ remote: dummy-remote
+ state: latest
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_latest_result
+
+- name: Verify idempotency of state=latest with list partially installed test result - {{ method }}
+ assert:
+ that:
+ - double_latest_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+- name: Cleanup after state=present with list test - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App2
+ - com.dummy.App3
+ state: absent
+ method: "{{ method }}"
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 0ed3c2817..8fd88074b 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
@@ -16,7 +16,6 @@
- name: include tasks
block:
-
- name: include tasks to perform basic tests
include_tasks: tests/00-basic.yml
@@ -50,3 +49,6 @@
- name: include tasks to test optional spaces in section headings
include_tasks: tests/07-section_name_spaces.yml
+
+ - name: include tasks to test section_has_values
+ include_tasks: tests/08-section.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml
new file mode 100644
index 000000000..4f3a135e1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/08-section.yml
@@ -0,0 +1,341 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/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 section selection
+
+- name: test-section 1 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+
+ dest: "{{ output_file }}"
+
+- name: test-section 1 - Modify starting ini file
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ option: car
+ value: volvo
+ state: present
+ register: result1
+
+- name: test-section 1 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 1 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+ car = volvo
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 1 - Option was added to first section
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'option added'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 2 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+
+ dest: "{{ output_file }}"
+
+- name: test-section 2 - Modify starting ini file
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: beverage
+ value: pineapple juice
+ option: car
+ value: volvo
+ state: present
+ register: result1
+
+- name: test-section 2 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 2 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+ car = volvo
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 2 - Option added to second section specified with section_has_values
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'option added'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 3 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+
+ dest: "{{ output_file }}"
+
+- name: test-section 3 - Modify starting ini file
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: beverage
+ value: pineapple juice
+ option: fav
+ value: lemonade
+ state: absent
+ register: result1
+
+- name: test-section 3 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 3 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ beverage = pineapple juice
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 3 - Option was removed from specified section
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'option changed'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 4 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+
+ dest: "{{ output_file }}"
+
+- name: test-section 4 - Modify starting ini file
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: beverage
+ value: alligator slime
+ option: fav
+ value: tea
+ state: present
+ register: result1
+
+- name: test-section 4 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 4 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ fav = lemonade
+ beverage = pineapple juice
+ [drinks]
+ beverage = alligator slime
+ fav = tea
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 4 - New section created, including required values
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'section and option added'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 5 - Modify test-section 4 result file
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: fav
+ value: lemonade
+ - option: beverage
+ value: pineapple juice
+ state: absent
+ register: result1
+
+- name: test-section 5 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 5 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ beverage = alligator slime
+ fav = tea
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 5 - Section removed as specified
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'section removed'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 6 - Modify test-section 5 result file with multiple values
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: fav
+ values:
+ - cherry
+ - lemon
+ - vanilla
+ - option: beverage
+ value: pineapple juice
+ state: present
+ option: fav
+ values:
+ - vanilla
+ - grape
+ exclusive: false
+ register: result1
+
+- name: test-section 6 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 6 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ beverage = alligator slime
+ fav = tea
+ [drinks]
+ beverage = pineapple juice
+ fav = vanilla
+ fav = grape
+ fav = cherry
+ fav = lemon
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 6 - New section added
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'section and option added'
+ - output1 == expected1
+
+# ----------------
+
+- name: test-section 7 - Modify test-section 6 result file with exclusive value
+ ini_file:
+ dest: "{{ output_file }}"
+ section: drinks
+ section_has_values:
+ - option: fav
+ value: vanilla
+ state: present
+ option: fav
+ value: cherry
+ exclusive: true
+ register: result1
+
+- name: test-section 7 - Read modified file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-section 7 - Create expected result
+ set_fact:
+ expected1: |
+ [drinks]
+ fav = lemonade
+ beverage = orange juice
+
+ [drinks]
+ beverage = alligator slime
+ fav = tea
+ [drinks]
+ beverage = pineapple juice
+ fav = cherry
+ output1: "{{ output_content.content | b64decode }}"
+
+- name: test-section 7 - Option changed
+ assert:
+ that:
+ - result1 is changed
+ - result1.msg == 'option changed'
+ - output1 == expected1
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md
new file mode 100644
index 000000000..cd1152dad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/README.md
@@ -0,0 +1,20 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+# Running keycloak_client_rolescope module integration test
+
+To run Keycloak component info module's integration test, start a keycloak server using Docker:
+
+ 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 integration tests:
+
+ ansible-test integration -v keycloak_client_rolescope --allow-unsupported --docker fedora35 --docker-network host
+
+Cleanup:
+
+ docker stop mykeycloak
+
+
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/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_client_rolescope/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml
new file mode 100644
index 000000000..8675c9548
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/tasks/main.yml
@@ -0,0 +1,317 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-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: Create a Keycloak realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ item }}"
+ realm: "{{ realm }}"
+ with_items:
+ - "{{ realm_role_admin }}"
+ - "{{ realm_role_user }}"
+
+- name: Client private
+ 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_name_private }}"
+ state: present
+ redirect_uris:
+ - "https://my-backend-api.c.org/"
+ fullScopeAllowed: True
+ attributes: '{{client_attributes1}}'
+ public_client: False
+
+- name: Create a Keycloak client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ name: "{{ item }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_private }}"
+ with_items:
+ - "{{ client_role_admin }}"
+ - "{{ client_role_user }}"
+
+- name: Client public
+ 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_name_public }}"
+ redirect_uris:
+ - "https://my-onepage-app-frontend.c.org/"
+ attributes: '{{client_attributes1}}'
+ full_scope_allowed: False
+ public_client: True
+
+
+- name: Map roles to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ client_scope_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ client_role_admin }}"
+ - "{{ client_role_user }}"
+ register: result
+
+- name: Assert mapping created
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 2
+
+- name: remap role user to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ client_scope_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ client_role_user }}"
+ register: result
+
+- name: Assert mapping created
+ assert:
+ that:
+ - result is not changed
+ - result.end_state | length == 2
+
+- name: Remove Map role admin to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ client_scope_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ client_role_admin }}"
+ state: absent
+ register: result
+
+- name: Assert mapping deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 1
+ - result.end_state[0].name == client_role_user
+
+- name: Map missing roles to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ client_scope_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ client_role_admin }}"
+ - "{{ client_role_not_exists }}"
+ ignore_errors: true
+ register: result
+
+- name: Assert failed mapping missing role
+ assert:
+ that:
+ - result is failed
+
+- name: Map roles duplicate
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ client_scope_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ client_role_admin }}"
+ - "{{ client_role_admin }}"
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 2
+
+- name: Map roles to private client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_private }}"
+ role_names:
+ - "{{ realm_role_admin }}"
+ ignore_errors: true
+ register: result
+
+- name: Assert failed mapping role to full scope client
+ assert:
+ that:
+ - result is failed
+
+- name: Map realm role to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names:
+ - "{{ realm_role_admin }}"
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 1
+
+- name: Map two realm roles to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names:
+ - "{{ realm_role_admin }}"
+ - "{{ realm_role_user }}"
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 2
+
+- name: Unmap all realm roles to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names:
+ - "{{ realm_role_admin }}"
+ - "{{ realm_role_user }}"
+ state: absent
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 0
+
+- name: Map missing realm role to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names:
+ - "{{ realm_role_not_exists }}"
+ ignore_errors: true
+ register: result
+
+- name: Assert failed mapping missing realm role
+ assert:
+ that:
+ - result is failed
+
+- name: Check-mode try to Map realm roles to public client
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names:
+ - "{{ realm_role_admin }}"
+ - "{{ realm_role_user }}"
+ check_mode: true
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is changed
+ - result.end_state | length == 2
+
+- name: Check-mode step two, check if change where applied
+ community.general.keycloak_client_rolescope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_name_public }}"
+ role_names: []
+ register: result
+
+- name: Assert result
+ assert:
+ that:
+ - result is not changed
+ - result.end_state | length == 0 \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.yml
new file mode 100644
index 000000000..8bd59398b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client_rolescope/vars/main.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
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+
+
+client_name_private: backend-client-private
+client_role_admin: client-role-admin
+client_role_user: client-role-user
+client_role_not_exists: client-role-missing
+
+client_name_public: frontend-client-public
+
+
+realm_role_admin: realm-role-admin
+realm_role_user: realm-role-user
+realm_role_not_exists: client-role-missing
+
+
+client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false, "client.secret.creation.time": 0}
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml
index 217c020ca..8a88bca45 100644
--- a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml
@@ -19,13 +19,13 @@
- item.0 == 'nl'
- item.1 == 'Netherlands'
vars:
- - lmdb_kv_db: jp.mdb
+ lmdb_kv_db: jp.mdb
with_community.general.lmdb_kv:
- n*
- assert:
that:
- item == 'Belgium'
vars:
- - lmdb_kv_db: jp.mdb
+ lmdb_kv_db: jp.mdb
with_community.general.lmdb_kv:
- be
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt
new file mode 100644
index 000000000..d75aaeac2
--- /dev/null
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt
@@ -0,0 +1,17 @@
+plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
+plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt'
+plugins/modules/homectl.py import-3.12 # Uses deprecated stdlib library 'crypt'
+plugins/modules/iptables_state.py validate-modules:undocumented-parameter # params _back and _timeout used by action plugin
+plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
+plugins/modules/osx_defaults.py validate-modules:parameter-state-invalid-choice
+plugins/modules/parted.py validate-modules:parameter-state-invalid-choice
+plugins/modules/rax_files_objects.py use-argspec-type-path # module deprecated - removed in 9.0.0
+plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice # module deprecated - removed in 9.0.0
+plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
+plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
+plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
+plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
+plugins/modules/xfconf.py validate-modules:return-syntax-error
+plugins/module_utils/univention_umc.py pylint:use-yield-from # suggested construct does not work with Python 2
+tests/unit/compat/mock.py pylint:use-yield-from # suggested construct does not work with Python 2
+tests/unit/plugins/modules/test_gio_mime.yaml no-smart-quotes
diff --git a/ansible_collections/community/general/tests/sanity/ignore-2.18.txt.license b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/sanity/ignore-2.18.txt.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/unit/plugins/callback/test_loganalytics.py b/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py
index 17932ed5f..4d7c2c9db 100644
--- a/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py
+++ b/ansible_collections/community/general/tests/unit/plugins/callback/test_loganalytics.py
@@ -9,8 +9,8 @@ from ansible.executor.task_result import TaskResult
from ansible_collections.community.general.tests.unit.compat import unittest
from ansible_collections.community.general.tests.unit.compat.mock import patch, Mock
from ansible_collections.community.general.plugins.callback.loganalytics import AzureLogAnalyticsSource
-from datetime import datetime
+from datetime import datetime
import json
import sys
@@ -32,10 +32,10 @@ class TestAzureLogAnalytics(unittest.TestCase):
if sys.version_info < (3, 2):
self.assertRegex = self.assertRegexpMatches
- @patch('ansible_collections.community.general.plugins.callback.loganalytics.datetime')
+ @patch('ansible_collections.community.general.plugins.callback.loganalytics.now')
@patch('ansible_collections.community.general.plugins.callback.loganalytics.open_url')
- def test_overall(self, open_url_mock, mock_datetime):
- mock_datetime.utcnow.return_value = datetime(2020, 12, 1)
+ def test_overall(self, open_url_mock, mock_now):
+ mock_now.return_value = datetime(2020, 12, 1)
result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields)
self.loganalytics.send_event(workspace_id='01234567-0123-0123-0123-01234567890a',
@@ -52,10 +52,10 @@ class TestAzureLogAnalytics(unittest.TestCase):
self.assertEqual(sent_data['event']['uuid'], 'myuuid')
self.assertEqual(args[0], 'https://01234567-0123-0123-0123-01234567890a.ods.opinsights.azure.com/api/logs?api-version=2016-04-01')
- @patch('ansible_collections.community.general.plugins.callback.loganalytics.datetime')
+ @patch('ansible_collections.community.general.plugins.callback.loganalytics.now')
@patch('ansible_collections.community.general.plugins.callback.loganalytics.open_url')
- def test_auth_headers(self, open_url_mock, mock_datetime):
- mock_datetime.utcnow.return_value = datetime(2020, 12, 1)
+ def test_auth_headers(self, open_url_mock, mock_now):
+ mock_now.return_value = datetime(2020, 12, 1)
result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields)
self.loganalytics.send_event(workspace_id='01234567-0123-0123-0123-01234567890a',
diff --git a/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py b/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py
index ddcdae24c..c09540fc0 100644
--- a/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py
+++ b/ansible_collections/community/general/tests/unit/plugins/callback/test_splunk.py
@@ -27,10 +27,10 @@ class TestSplunkClient(unittest.TestCase):
self.mock_host = Mock('MockHost')
self.mock_host.name = 'myhost'
- @patch('ansible_collections.community.general.plugins.callback.splunk.datetime')
+ @patch('ansible_collections.community.general.plugins.callback.splunk.now')
@patch('ansible_collections.community.general.plugins.callback.splunk.open_url')
- def test_timestamp_with_milliseconds(self, open_url_mock, mock_datetime):
- mock_datetime.utcnow.return_value = datetime(2020, 12, 1)
+ def test_timestamp_with_milliseconds(self, open_url_mock, mock_now):
+ mock_now.return_value = datetime(2020, 12, 1)
result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields)
self.splunk.send_event(
@@ -45,10 +45,10 @@ class TestSplunkClient(unittest.TestCase):
self.assertEqual(sent_data['event']['host'], 'my-host')
self.assertEqual(sent_data['event']['ip_address'], '1.2.3.4')
- @patch('ansible_collections.community.general.plugins.callback.splunk.datetime')
+ @patch('ansible_collections.community.general.plugins.callback.splunk.now')
@patch('ansible_collections.community.general.plugins.callback.splunk.open_url')
- def test_timestamp_without_milliseconds(self, open_url_mock, mock_datetime):
- mock_datetime.utcnow.return_value = datetime(2020, 12, 1)
+ def test_timestamp_without_milliseconds(self, open_url_mock, mock_now):
+ mock_now.return_value = datetime(2020, 12, 1)
result = TaskResult(host=self.mock_host, task=self.mock_task, return_data={}, task_fields=self.task_fields)
self.splunk.send_event(
diff --git a/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py b/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py
index 9270dd44e..04cad8d6c 100644
--- a/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py
+++ b/ansible_collections/community/general/tests/unit/plugins/lookup/test_bitwarden.py
@@ -6,6 +6,7 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
+import re
from ansible_collections.community.general.tests.unit.compat import unittest
from ansible_collections.community.general.tests.unit.compat.mock import patch
@@ -13,8 +14,10 @@ from ansible.errors import AnsibleError
from ansible.module_utils import six
from ansible.plugins.loader import lookup_loader
from ansible_collections.community.general.plugins.lookup.bitwarden import Bitwarden
+from ansible.parsing.ajson import AnsibleJSONEncoder
MOCK_COLLECTION_ID = "3b12a9da-7c49-40b8-ad33-aede017a7ead"
+MOCK_ORGANIZATION_ID = "292ba0c6-f289-11ee-9301-ef7b639ccd2a"
MOCK_RECORDS = [
{
@@ -48,7 +51,7 @@ MOCK_RECORDS = [
"name": "a_test",
"notes": None,
"object": "item",
- "organizationId": None,
+ "organizationId": MOCK_ORGANIZATION_ID,
"passwordHistory": [
{
"lastUsedDate": "2022-07-26T23:03:23.405Z",
@@ -68,9 +71,7 @@ MOCK_RECORDS = [
"type": 1
},
{
- "collectionIds": [
- MOCK_COLLECTION_ID
- ],
+ "collectionIds": [],
"deletedDate": None,
"favorite": False,
"folderId": None,
@@ -106,10 +107,30 @@ MOCK_RECORDS = [
"name": "dupe_name",
"notes": None,
"object": "item",
- "organizationId": None,
+ "organizationId": MOCK_ORGANIZATION_ID,
"reprompt": 0,
"revisionDate": "2022-07-27T03:42:46.673Z",
"type": 1
+ },
+ {
+ "collectionIds": [],
+ "deletedDate": None,
+ "favorite": False,
+ "folderId": None,
+ "id": "2bf517be-fb13-11ee-be89-a345aa369a94",
+ "login": {
+ "password": "e",
+ "passwordRevisionDate": None,
+ "totp": None,
+ "username": "f"
+ },
+ "name": "non_collection_org_record",
+ "notes": None,
+ "object": "item",
+ "organizationId": MOCK_ORGANIZATION_ID,
+ "reprompt": 0,
+ "revisionDate": "2024-14-15T11:30:00.000Z",
+ "type": 1
}
]
@@ -118,11 +139,41 @@ class MockBitwarden(Bitwarden):
unlocked = True
- def _get_matches(self, search_value=None, search_field="name", collection_id=None):
- if not search_value and collection_id:
- return list(filter(lambda record: collection_id in record['collectionIds'], MOCK_RECORDS))
+ def _run(self, args, stdin=None, expected_rc=0):
+ if args[0] == 'get':
+ if args[1] == 'item':
+ for item in MOCK_RECORDS:
+ if item.get('id') == args[2]:
+ return AnsibleJSONEncoder().encode(item), ''
+ if args[0] == 'list':
+ if args[1] == 'items':
+ try:
+ search_value = args[args.index('--search') + 1]
+ except ValueError:
+ search_value = None
+
+ try:
+ collection_to_filter = args[args.index('--collectionid') + 1]
+ except ValueError:
+ collection_to_filter = None
+
+ try:
+ organization_to_filter = args[args.index('--organizationid') + 1]
+ except ValueError:
+ organization_to_filter = None
+
+ items = []
+ for item in MOCK_RECORDS:
+ if search_value and not re.search(search_value, item.get('name')):
+ continue
+ if collection_to_filter and collection_to_filter not in item.get('collectionIds', []):
+ continue
+ if organization_to_filter and item.get('organizationId') != organization_to_filter:
+ continue
+ items.append(item)
+ return AnsibleJSONEncoder().encode(items), ''
- return list(filter(lambda record: record[search_field] == search_value, MOCK_RECORDS))
+ return '[]', ''
class LoggedOutMockBitwarden(MockBitwarden):
@@ -194,4 +245,19 @@ class TestLookupModule(unittest.TestCase):
@patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden())
def test_bitwarden_plugin_full_collection(self):
# Try to retrieve the full records of the given collection.
- self.assertEqual(MOCK_RECORDS, self.lookup.run(None, collection_id=MOCK_COLLECTION_ID)[0])
+ self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2]], self.lookup.run(None, collection_id=MOCK_COLLECTION_ID)[0])
+
+ @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden())
+ def test_bitwarden_plugin_full_organization(self):
+ self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2], MOCK_RECORDS[3]],
+ self.lookup.run(None, organization_id=MOCK_ORGANIZATION_ID)[0])
+
+ @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden())
+ def test_bitwarden_plugin_filter_organization(self):
+ self.assertEqual([MOCK_RECORDS[2]],
+ self.lookup.run(['dupe_name'], organization_id=MOCK_ORGANIZATION_ID)[0])
+
+ @patch('ansible_collections.community.general.plugins.lookup.bitwarden._bitwarden', new=MockBitwarden())
+ def test_bitwarden_plugin_full_collection_organization(self):
+ self.assertEqual([MOCK_RECORDS[0], MOCK_RECORDS[2]], self.lookup.run(None,
+ collection_id=MOCK_COLLECTION_ID, organization_id=MOCK_ORGANIZATION_ID)[0])