summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/rabbitmq
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/rabbitmq')
-rw-r--r--ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml239
-rw-r--r--ansible_collections/community/rabbitmq/CHANGELOG.rst17
-rw-r--r--ansible_collections/community/rabbitmq/FILES.json65
-rw-r--r--ansible_collections/community/rabbitmq/MANIFEST.json4
-rw-r--r--ansible_collections/community/rabbitmq/changelogs/changelog.yaml24
-rw-r--r--ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py3
-rw-r--r--ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py1
-rw-r--r--ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py15
-rw-r--r--ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py8
-rw-r--r--ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py504
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml4
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml4
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml4
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml2
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml131
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml4
-rw-r--r--ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml4
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt2
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.11.txt2
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt2
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt3
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt3
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt2
-rw-r--r--ansible_collections/community/rabbitmq/tests/sanity/ignore.txt2
-rw-r--r--ansible_collections/community/rabbitmq/tests/unit/compat/mock.py6
-rw-r--r--ansible_collections/community/rabbitmq/tests/unit/mock/loader.py2
-rwxr-xr-xansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh1
27 files changed, 714 insertions, 344 deletions
diff --git a/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml b/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml
index 7002adffa..69638bf11 100644
--- a/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml
+++ b/ansible_collections/community/rabbitmq/.azure-pipelines/azure-pipelines.yml
@@ -36,7 +36,7 @@ variables:
resources:
containers:
- container: default
- image: quay.io/ansible/azure-pipelines-test-container:3.0.0
+ image: quay.io/ansible/azure-pipelines-test-container:4.0.1
pool: Standard
@@ -54,77 +54,41 @@ stages:
- name: Units
test: 'devel/units/1'
- - stage: Ansible_2_14
- displayName: Sanity & Units 2.14
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- targets:
- - name: Sanity
- test: '2.14/sanity/1'
- - name: Units
- test: '2.14/units/1'
-
- - stage: Ansible_2_13
- displayName: Sanity & Units 2.13
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- targets:
- - name: Sanity
- test: '2.13/sanity/1'
- - name: Units
- test: '2.13/units/1'
-
- - stage: Ansible_2_12
- displayName: Sanity & Units 2.12
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- targets:
- - name: Sanity
- test: '2.12/sanity/1'
- - name: Units
- test: '2.12/units/1'
-
- - stage: Ansible_2_11
- displayName: Sanity & Units 2.11
+ - stage: Ansible_2_16
+ displayName: Sanity & Units 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
- test: '2.11/sanity/1'
+ test: '2.16/sanity/1'
- name: Units
- test: '2.11/units/1'
+ test: '2.16/units/1'
- - stage: Ansible_2_10
- displayName: Sanity & Units 2.10
+ - stage: Ansible_2_15
+ displayName: Sanity & Units 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
- test: '2.10/sanity/1'
+ test: '2.15/sanity/1'
- name: Units
- test: '2.10/units/1'
+ test: '2.15/units/1'
- - stage: Ansible_2_9
- displayName: Sanity & Units 2.9
+ - stage: Ansible_2_14
+ displayName: Sanity & Units 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
targets:
- name: Sanity
- test: '2.9/sanity/1'
+ test: '2.14/sanity/1'
- name: Units
- test: '2.9/units/1'
+ test: '2.14/units/1'
### Docker
- stage: Docker_devel
@@ -163,113 +127,50 @@ stages:
#- name: Ubuntu 20.04
# test: ubuntu2004
- - stage: Docker_2_14
- displayName: Docker 2.14
+ - stage: Docker_2_16
+ displayName: Docker 2.16
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
- testFormat: 2.14/linux/{0}/1
+ testFormat: 2.16/linux/{0}/1
targets:
- name: Ubuntu 22.04
test: ubuntu2204
- # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python
- # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller
- # and target container which is probably why rabbitmq_publish is not able to connect to
- # rabbitmq on localhost.
- #- name: Ubuntu 20.04
- # test: ubuntu2004
-
- - stage: Docker_2_13
- displayName: Docker 2.13
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- testFormat: 2.13/linux/{0}/1
- targets:
- #- name: Ubuntu 18.04
- # test: ubuntu1804
- - name: Ubuntu 20.04
- test: ubuntu2004
-
- - stage: Docker_2_12
- displayName: Docker 2.12
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- testFormat: 2.12/linux/{0}/1
- targets:
- #- name: Ubuntu 18.04
- # test: ubuntu1804
- - name: Ubuntu 20.04
- test: ubuntu2004
-
- - stage: Docker_2_11
- displayName: Docker 2.11
- dependsOn: []
- jobs:
- - template: templates/matrix.yml
- parameters:
- testFormat: 2.11/linux/{0}/1
- targets:
- # NOTE: update integration roles to support platform before enabling here.
- #- name: CentOS 6
- # test: centos6
- #- name: CentOS 7
- # test: centos7
- #- name: Fedora 32
- # test: fedora32
- #- name: Fedora 33
- # test: fedora33
- #- name: openSUSE 15 py2
- # test: opensuse15py2
- #- name: openSUSE 15 py3
- # test: opensuse15
- - name: Ubuntu 18.04
- test: ubuntu1804
- - name: Ubuntu 20.04
- test: ubuntu2004
- - stage: Docker_2_10
- displayName: Docker 2.10
+ - stage: Docker_2_15
+ displayName: Docker 2.15
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
- testFormat: 2.10/linux/{0}/1
+ testFormat: 2.15/linux/{0}/1
targets:
- # NOTE: update integration roles to support platform before enabling here.
- #- name: CentOS 6
- # test: centos6
- #- name: CentOS 7
- # test: centos7
- #- name: Fedora 31
- # test: fedora31
- #- name: Fedora 32
- # test: fedora32
- #- name: openSUSE 15 py2
- # test: opensuse15py2
- #- name: openSUSE 15 py3
- # test: opensuse15
- - name: Ubuntu 18.04
- test: ubuntu1804
- - name: Ubuntu 20.04
- test: ubuntu2004
+ - name: Ubuntu 22.04
+ test: ubuntu2204
+ # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python
+ # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller
+ # and target container which is probably why rabbitmq_publish is not able to connect to
+ # rabbitmq on localhost.
+ #- name: Ubuntu 20.04
+ # test: ubuntu2004
- - stage: Docker_2_9
- displayName: Docker 2.9
+ - stage: Docker_2_14
+ displayName: Docker 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
- testFormat: 2.9/linux/{0}/1
+ testFormat: 2.14/linux/{0}/1
targets:
- # NOTE: update integration roles to support platform before adding here.
- - name: Ubuntu 18.04
- test: ubuntu1804 # freezes in rabbitmq_setup
- # ansible-test 2.9 does not support 20.04 (image not included in its test-containers list)
+ - name: Ubuntu 22.04
+ test: ubuntu2204
+ # Currently 20.04 is causing devel to fail. This maybe due to Ubuntu 20.04 running python
+ # 3.8, however, ansible-test requires 3.9+. This means ansible test spins up a controller
+ # and target container which is probably why rabbitmq_publish is not able to connect to
+ # rabbitmq on localhost.
+ #- name: Ubuntu 20.04
+ # test: ubuntu2004
### Remote
# - stage: Remote_devel
@@ -288,74 +189,16 @@ stages:
# test: freebsd/11.4
# - name: FreeBSD 12.2
# test: freebsd/12.2
-# - stage: Remote_2_11
-# displayName: Remote 2.11
-# dependsOn: []
-# jobs:
-# - template: templates/matrix.yml
-# parameters:
-# testFormat: 2.11/{0}/1
-# targets:
-# - name: RHEL 7.9
-# test: rhel/7.9
-# - name: RHEL 8.3
-# test: rhel/8.3
-# - name: FreeBSD 11.4
-# test: freebsd/11.4
-# - name: FreeBSD 12.2
-# test: freebsd/12.2
-# - stage: Remote_2_10
-# displayName: Remote 2.10
-# dependsOn: []
-# jobs:
-# - template: templates/matrix.yml
-# parameters:
-# testFormat: 2.10/{0}/1
-# targets:
-# - name: RHEL 7.8
-# test: rhel/7.8
-# - name: RHEL 8.2
-# test: rhel/8.2
-# - name: FreeBSD 11.1
-# test: freebsd/11.1
-# - name: FreeBSD 12.1
-# test: freebsd/12.1
-# - stage: Remote_2_9
-# displayName: Remote 2.9
-# dependsOn: []
-# jobs:
-# - template: templates/matrix.yml
-# parameters:
-# testFormat: 2.9/{0}/1
-# targets:
-# - name: RHEL 7.8
-# test: rhel/7.8
-# - name: RHEL 8.2
-# test: rhel/8.2
-# - name: FreeBSD 11.1
-# test: freebsd/11.1
-# - name: FreeBSD 12.1
-# test: freebsd/12.1
+
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Ansible_devel
+ - Ansible_2_15
- Ansible_2_14
- - Ansible_2_13
- - Ansible_2_12
- - Ansible_2_11
- - Ansible_2_10
- - Ansible_2_9
- Docker_devel
+ - Docker_2_15
- Docker_2_14
- - Docker_2_13
- - Docker_2_12
- - Docker_2_11
- - Docker_2_10
- - Docker_2_9
#- Remote_devel
- #- Remote_2_11
- #- Remote_2_10
- #- Remote_2_9
jobs:
- template: templates/coverage.yml
diff --git a/ansible_collections/community/rabbitmq/CHANGELOG.rst b/ansible_collections/community/rabbitmq/CHANGELOG.rst
index 2972a9aa7..4f376603c 100644
--- a/ansible_collections/community/rabbitmq/CHANGELOG.rst
+++ b/ansible_collections/community/rabbitmq/CHANGELOG.rst
@@ -4,6 +4,20 @@ Community.Rabbitmq Release Notes
.. contents:: Topics
+v1.3.0
+======
+
+Release Summary
+---------------
+
+This is the minor release of the ``community.rabbitmq`` collection.
+This changelog contains all changes to the modules and plugins in this collection
+that have been made after the 1.2.3 release.
+
+Minor Changes
+-------------
+
+- rabbitmq_user - add support to user manipulation through RabbitMQ API (https://github.com/ansible-collections/community.rabbitmq/issues/76)
v1.2.3
======
@@ -15,7 +29,6 @@ This is the minor release of the ``community.rabbitmq`` collection.
This changelog contains all changes to the modules and plugins in this collection
that have been made after the 1.2.2 release.
-
Minor Changes
-------------
@@ -25,8 +38,8 @@ Minor Changes
Bugfixes
--------
-- rabbitmq_queue - fixing an issue where a special character in the queue name would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114).
- Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139 & https://github.com/ansible-collections/community.rabbitmq/pull/141).
+- rabbitmq_queue - fixing an issue where a special character in the queue name would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114).
v1.2.2
======
diff --git a/ansible_collections/community/rabbitmq/FILES.json b/ansible_collections/community/rabbitmq/FILES.json
index 386bcdee6..c3722e646 100644
--- a/ansible_collections/community/rabbitmq/FILES.json
+++ b/ansible_collections/community/rabbitmq/FILES.json
@@ -109,7 +109,7 @@
"name": ".azure-pipelines/azure-pipelines.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fcad40ddb0bcc93a39f7d1a5085a0cda0b6c16cfcc52d8874a23ddc090f0c57f",
+ "chksum_sha256": "16db5589035b7434f5d3a7025654cd37a6b1b283f406688fc07ca2fa0805a33d",
"format": 1
},
{
@@ -123,7 +123,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2c1ac1a9869d7c8d4e39046dab344e152b41c4568e830c835c5a160c5c7f4d9f",
+ "chksum_sha256": "9bc8251d2d005b494b776c350eae47d6af7d7863cd82cbe1bb696a7b84b87815",
"format": 1
},
{
@@ -186,7 +186,7 @@
"name": "plugins/lookup/rabbitmq.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b9c692de8e40a03374e0ca861a7878a0fd62e030b6b318dfc92f4b8ae20a688e",
+ "chksum_sha256": "cfe3e5e5754f50515b05ab3d4e4079aa4bc6c64c449f75e5c8e791d83b68377c",
"format": 1
},
{
@@ -207,7 +207,7 @@
"name": "plugins/module_utils/rabbitmq.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "e0f334c9bff8d4198ee16bec49f13f08da5b9c43191109cab7c17d26bbddf218",
+ "chksum_sha256": "612bbc76033437090e05aa16b797e6003d7d90e8a0ced59d28b27ad82f970368",
"format": 1
},
{
@@ -256,7 +256,7 @@
"name": "plugins/modules/rabbitmq_parameter.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2cd6c3187093db8314603108d9d91c318c784af4bd07cc4f196a6bc01dcddc33",
+ "chksum_sha256": "d2d85dec30694641f91cccbddb5c827462cebd51655273462ba0280a35e4e4a9",
"format": 1
},
{
@@ -277,7 +277,7 @@
"name": "plugins/modules/rabbitmq_publish.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d5585f87fd00075bad137a8b185cd5d9fabc8ae7576629e8b01c200610e8177a",
+ "chksum_sha256": "1c0c9680fe5d3d6fe7d77df6bc63fe44d3269af82e3238d44e8d28efb958fff9",
"format": 1
},
{
@@ -298,7 +298,7 @@
"name": "plugins/modules/rabbitmq_user.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5fe7cd8150b3b76e87f8f86fe164f89070d9f62a61411d6b84e004c18949451f",
+ "chksum_sha256": "df9c298b4a460cee35c274032a83cc402a843ffc63f53f40376d22cead3c70e3",
"format": 1
},
{
@@ -375,7 +375,7 @@
"name": "tests/integration/targets/lookup_rabbitmq/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0",
+ "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c",
"format": 1
},
{
@@ -718,7 +718,7 @@
"name": "tests/integration/targets/rabbitmq_publish/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0",
+ "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c",
"format": 1
},
{
@@ -767,7 +767,7 @@
"name": "tests/integration/targets/rabbitmq_queue/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0",
+ "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c",
"format": 1
},
{
@@ -865,7 +865,7 @@
"name": "tests/integration/targets/rabbitmq_user/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "27b82af4f4e91ff9565ee5a834d7b93b0322b25dec30ab06a23d07b178f515c9",
+ "chksum_sha256": "7b47e3c3e8b4970ef2b1d8a97410a8224c72b0c949e423e385d238ded830f3b9",
"format": 1
},
{
@@ -876,6 +876,13 @@
"format": 1
},
{
+ "name": "tests/integration/targets/rabbitmq_user/tasks/tests_api.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "87e87bd203d2432fe211e49940b58e9b409d97f735e898f12c15408b041e530c",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/rabbitmq_user/aliases",
"ftype": "file",
"chksum_type": "sha256",
@@ -914,7 +921,7 @@
"name": "tests/integration/targets/rabbitmq_user_limits/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0",
+ "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c",
"format": 1
},
{
@@ -1012,7 +1019,7 @@
"name": "tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4191eddb2b4316a026b0b6073752948393447541f7cd615799e765ab6bca6fb0",
+ "chksum_sha256": "1de7cad29c82819b7983e39a90358a55ff81eb7dc54d27d05ae665073379939c",
"format": 1
},
{
@@ -1212,20 +1219,6 @@
"format": 1
},
{
- "name": "tests/sanity/ignore-2.10.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
- "name": "tests/sanity/ignore-2.11.txt",
- "ftype": "file",
- "chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
- "format": 1
- },
- {
"name": "tests/sanity/ignore-2.12.txt",
"ftype": "file",
"chksum_type": "sha256",
@@ -1250,21 +1243,21 @@
"name": "tests/sanity/ignore-2.15.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
+ "chksum_sha256": "f9e62f04368d06e3fee2abe014f49bc1696a1478a4d0a8e32fb5c1dae693c43e",
"format": 1
},
{
- "name": "tests/sanity/ignore-2.9.txt",
+ "name": "tests/sanity/ignore-2.16.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
+ "chksum_sha256": "7919c2c8970b1cac1d23835cdb9a3a250190bd789e4f24b3331dfca7ddbfd1ad",
"format": 1
},
{
- "name": "tests/sanity/ignore.txt",
+ "name": "tests/sanity/ignore-2.17.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "8b8815dcc93330716312b23095ad47d984bd7a039d20a5baa1127ce6d73ca6e8",
+ "chksum_sha256": "7919c2c8970b1cac1d23835cdb9a3a250190bd789e4f24b3331dfca7ddbfd1ad",
"format": 1
},
{
@@ -1299,7 +1292,7 @@
"name": "tests/unit/compat/mock.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0af958450cf6de3fbafe94b1111eae8ba5a8dbe1d785ffbb9df81f26e4946d99",
+ "chksum_sha256": "77edbe32e554aef3000b7d3c0bf7ae96c307cb0f0943fe91a4dfa4d840ba7fc9",
"format": 1
},
{
@@ -1327,7 +1320,7 @@
"name": "tests/unit/mock/loader.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "cfe3480f0eae6d3723ee62d01d00a0e9f58fcdc082ea1d8e4836157c56d4fa95",
+ "chksum_sha256": "7307b7f5d85fc5a4de7fe47f0b5f008e57fb24a0fe2702f09d9d7e80afbc44d8",
"format": 1
},
{
@@ -1481,7 +1474,7 @@
"name": "tests/utils/shippable/shippable.sh",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fbd386cce60ec181967826a2accc28b054021c67b124b056120dc37fca1c9a10",
+ "chksum_sha256": "60fa0850685439febcef31fe85586a7f346e9155fa563be2549365a988c3fabe",
"format": 1
},
{
@@ -1516,7 +1509,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0ebfd06c05555985fd1766d51b262d7d16bdcbb7e62a556533a583c7804cf664",
+ "chksum_sha256": "65a2321cc2f0390f03fe9d00e12d2fa8fc98b65d1e54a44325427abda483b724",
"format": 1
},
{
diff --git a/ansible_collections/community/rabbitmq/MANIFEST.json b/ansible_collections/community/rabbitmq/MANIFEST.json
index aef8fe4bf..9653a4d58 100644
--- a/ansible_collections/community/rabbitmq/MANIFEST.json
+++ b/ansible_collections/community/rabbitmq/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "rabbitmq",
- "version": "1.2.3",
+ "version": "1.3.0",
"authors": [
"Ansible (https://github.com/ansible)",
"community.rabbitmq"
@@ -24,7 +24,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5ccdbf6355d35529c8944cfa5f572e21e987b5050135b9262c754cdcbc1c25d7",
+ "chksum_sha256": "e4a87617bfd273702d37e86b00a3e37f03b8242320e8ffa8f90d2f7b9b9cc975",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/rabbitmq/changelogs/changelog.yaml b/ansible_collections/community/rabbitmq/changelogs/changelog.yaml
index ee3c424ba..db72d33e0 100644
--- a/ansible_collections/community/rabbitmq/changelogs/changelog.yaml
+++ b/ansible_collections/community/rabbitmq/changelogs/changelog.yaml
@@ -95,22 +95,21 @@ releases:
1.2.3:
changes:
bugfixes:
+ - Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139
+ & https://github.com/ansible-collections/community.rabbitmq/pull/141).
- rabbitmq_queue - fixing an issue where a special character in the queue name
would result in an API error (https://github.com/ansible-collections/community.rabbitmq/issues/114).
minor_changes:
- rabbitmq_exchange - adding ability to specify exchange types that are enabled
- via plugins. I(x-random), I(x-consistent-hash) and I(x-recent-history)
- (https://github.com/ansible-collections/community.rabbitmq/pull/142).
+ via plugins. I(x-random), I(x-consistent-hash) and I(x-recent-history) (https://github.com/ansible-collections/community.rabbitmq/pull/142).
- rabbitmq_publish - fixing issue with publishing to exchanges and adding exchange
documentation examples. Publishing to an exchange or queue is now mutually
- exclusive (https://github.com/ansible-collections/community.rabbitmq/pull/140).
- - Various CI fixes (https://github.com/ansible-collections/community.rabbitmq/pull/139 &
- https://github.com/ansible-collections/community.rabbitmq/pull/141).
+ exclusive (https://github.com/ansible-collections/community.rabbitmq/pull/140).
release_summary: 'This is the minor release of the ``community.rabbitmq`` collection.
This changelog contains all changes to the modules and plugins in this collection
- that have been made after the 1.2.1 release.'
+ that have been made after the 1.2.2 release.'
fragments:
- 1.2.3.yml
- 114-queue-name-escape.yml
@@ -118,3 +117,16 @@ releases:
- 140-fixing-publishing-to-exchanges.yaml
- 142-new-plugin-exchanges.yml
release_date: '2022-11-04'
+ 1.3.0:
+ changes:
+ minor_changes:
+ - rabbitmq_user - add support to user manipulation through RabbitMQ API (https://github.com/ansible-collections/community.rabbitmq/issues/76)
+ release_summary: 'This is the minor release of the ``community.rabbitmq`` collection.
+
+ This changelog contains all changes to the modules and plugins in this collection
+
+ that have been made after the 1.2.3 release.'
+ fragments:
+ - 1.3.0.yml
+ - 120-api-managed-users.yaml
+ release_date: '2024-03-31'
diff --git a/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py b/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py
index 9ecd97e5f..16a93868c 100644
--- a/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py
+++ b/ansible_collections/community/rabbitmq/plugins/lookup/rabbitmq.py
@@ -98,14 +98,13 @@ RETURN = """
import json
-from ansible.errors import AnsibleError, AnsibleParserError
+from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils._text import to_native, to_text
from ansible.utils.display import Display
try:
import pika
- from pika import spec
HAS_PIKA = True
except ImportError:
HAS_PIKA = False
diff --git a/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py b/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py
index f981c8539..5f00acc91 100644
--- a/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py
+++ b/ansible_collections/community/rabbitmq/plugins/module_utils/rabbitmq.py
@@ -21,7 +21,6 @@ PIKA_IMP_ERR = None
try:
import pika
import pika.exceptions
- from pika import spec
HAS_PIKA = True
except ImportError:
PIKA_IMP_ERR = traceback.format_exc()
diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py
index 5ecbd4ec4..8728bf757 100644
--- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py
+++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_parameter.py
@@ -55,6 +55,21 @@ EXAMPLES = r"""
name: local-username
value: '"guest"'
state: present
+
+- name: Create or update a shovel
+ vars:
+ payload:
+ src-protocol: "amqp091"
+ src-uri: "amqp://"
+ src-queue: "src-queue"
+ dest-protocol: "amqp091"
+ dest-uri: "amqp://guest:guest@example.com"
+ dest-queue: "dest-queue"
+ community.rabbitmq.rabbitmq_parameter:
+ component: shovel
+ name: "shovel-name"
+ value: "{{ payload | to_json }}"
+ state: present
"""
import json
from ansible.module_utils.basic import AnsibleModule
diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py
index 38b5a64bb..e4054deaa 100644
--- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py
+++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_publish.py
@@ -187,15 +187,7 @@ result:
'result': { 'content_type': 'text/plain', 'msg': 'Successfully published to queue test', 'queue': 'test' }
'''
-try:
- import pika
- HAS_PIKA = True
-except ImportError:
- HAS_PIKA = False
-
-
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_native, to_text
from ansible_collections.community.rabbitmq.plugins.module_utils.rabbitmq import RabbitClient
diff --git a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py
index 87d6864fc..b941b759f 100644
--- a/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py
+++ b/ansible_collections/community/rabbitmq/plugins/modules/rabbitmq_user.py
@@ -5,8 +5,8 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
-__metaclass__ = type
+__metaclass__ = type
DOCUMENTATION = r'''
---
@@ -30,7 +30,8 @@ options:
type: str
tags:
description:
- - User tags specified as comma delimited
+ - User tags specified as comma delimited.
+ - The suggested tags to use are management, policymaker, monitoring and administrator.
type: str
permissions:
description:
@@ -103,9 +104,36 @@ options:
description:
- C(on_create) will only set the password for newly created users. C(always) will update passwords if they differ.
type: str
- required: false
default: on_create
choices: ['on_create', 'always']
+ login_protocol:
+ description:
+ - Specify which TCP/IP protocol will be used.
+ type: str
+ default: http
+ choices: ['http', 'https']
+ version_added: '1.3.0'
+ login_host:
+ description:
+ - Hostname of API.
+ type: str
+ version_added: '1.3.0'
+ login_port:
+ description:
+ - login_port of access from API.
+ type: str
+ default: '15672'
+ version_added: '1.3.0'
+ login_user:
+ description:
+ - Administrator's username the management API.
+ type: str
+ version_added: '1.3.0'
+ login_password:
+ description:
+ - Login password of the management API.
+ type: str
+ version_added: '1.3.0'
'''
EXAMPLES = r'''
@@ -146,13 +174,64 @@ EXAMPLES = r'''
read_priv: .*
write_priv: 'prod\\.logging\\..*'
state: present
+
+- name: |-
+ Add or Update a user using the API
+ community.rabbitmq.rabbitmq_user:
+ user: joe
+ password: changeme
+ tags: monitoring
+ login_protocol: https
+ login_host: localhost
+ login_port: 15672
+ login_user: admin
+ login_password: changeadmin
+ permissions:
+ - vhost: /
+ configure_priv: .*
+ read_priv: .*
+ write_priv: .*
+ topic_permissions:
+ - vhost: /
+ exchange: amq.topic
+ read_priv: .*
+ write_priv: 'prod\\.logging\\..*'
+ state: present
+
+
+- name: |-
+ Remove a user using the API
+ community.rabbitmq.rabbitmq_user:
+ user: joe
+ password: changeme
+ tags: monitoring
+ login_protocol: https
+ login_host: localhost
+ login_port: 15672
+ login_user: admin
+ login_password: changeadmin
+ state: absent
+
'''
-import ansible_collections.community.rabbitmq.plugins.module_utils.version as Version
-import json
-import re
+import ansible_collections.community.rabbitmq.plugins.module_utils.version as Version # noqa: E402
+import json # noqa: E402
+import re # noqa: E402
+
+from ansible.module_utils.six.moves.urllib import parse
+
+import traceback
+
+REQUESTS_IMP_ERR = None
+try:
+ import requests
+
+ HAS_REQUESTS = True
+except ImportError:
+ REQUESTS_IMP_ERR = traceback.format_exc()
+ HAS_REQUESTS = False
-from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.basic import AnsibleModule # noqa: E402
from ansible.module_utils.common.collections import count
@@ -193,9 +272,24 @@ def first(iterable):
return next(iter(iterable))
+def treat_permissions_for_api(permissions):
+ return {
+ "configure": permissions.get('configure') if permissions.get('configure') else '^$',
+ "write": permissions.get('write') if permissions.get('write') else '^$',
+ "read": permissions.get('read') if permissions.get('read') else '^$'
+ }
+
+
+def treat_topic_permissions_for_api(permissions):
+ return {"exchange": permissions.get('exchange'), "write": permissions.get('write'),
+ "read": permissions.get('read')}
+
+
class RabbitMqUser(object):
def __init__(self, module, username, password, tags, permissions,
- topic_permissions, node, bulk_permissions=False):
+ topic_permissions, node, bulk_permissions=False,
+ login_protocol=None, login_host=None, login_port=None,
+ login_user=None, login_password=None):
self.module = module
self.username = username
self.password = password or ''
@@ -204,12 +298,21 @@ class RabbitMqUser(object):
self.permissions = as_permission_dict(permissions)
self.topic_permissions = as_topic_permission_dict(topic_permissions)
self.bulk_permissions = bulk_permissions
+ self.login_protocol = login_protocol
+ self.login_host = login_host
+ self.login_port = login_port
+ self.login_user = login_user
+ self.login_password = login_password
self.existing_tags = None
self.existing_permissions = dict()
self.existing_topic_permissions = dict()
- self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
- self._version = self._check_version()
+ if self.login_host is not None:
+ self._rabbitmqctl = module.get_bin_path('rabbitmqctl', False)
+ self._version = None
+ else:
+ self._rabbitmqctl = module.get_bin_path('rabbitmqctl', True)
+ self._version = self._check_version()
def _check_version(self):
"""Get the version of the RabbitMQ server."""
@@ -233,6 +336,7 @@ class RabbitMqUser(object):
version of `rabbitmqctl` we are using, so we will try to use the JSON formatter and see
what happens. In some versions of
"""
+
def int_list_to_str(ints):
return ''.join([chr(i) for i in ints])
@@ -318,22 +422,39 @@ class RabbitMqUser(object):
If the version of the node is >= 3.7.6 the JSON formatter will be used, otherwise the plaintext will be
parsed.
"""
- if self._version >= Version.StrictVersion('3.7.6'):
- users = dict([(user_entry['user'], user_entry['tags'])
- for user_entry in json.loads(self._exec(['list_users', '--formatter', 'json']))])
+ users = dict()
+ if self.login_host is not None:
+ response = self.request_users_api('GET')
+ if response.status_code == 200:
+ if isinstance(response.json(), list):
+ users = dict([(user_entry['name'], user_entry['tags']) for user_entry in response.json()])
+ else:
+ users = {response.json()['name']: response.json()['tags']}
+ elif response.status_code == 404:
+ return None
+ else:
+ self.module.fail_json(
+ msg="Error getting the user",
+ status=response.status_code,
+ details=response.text
+ )
else:
- users = self._exec(['list_users'])
+ if self._version >= Version.StrictVersion('3.7.6'):
+ users = dict([(user_entry['user'], user_entry['tags'])
+ for user_entry in json.loads(self._exec(['list_users', '--formatter', 'json']))])
+ else:
+ users = self._exec(['list_users'])
- def process_tags(tags):
- if not tags:
- return list()
- return tags.replace('[', '').replace(']', '').replace(' ', '').strip('\t').split(',')
+ def process_tags(tags):
+ if not tags:
+ return list()
+ return tags.replace('[', '').replace(']', '').replace(' ', '').strip('\t').split(',')
- users_and_tags = [user_entry.split('\t') for user_entry in users.strip().split('\n')]
+ users_and_tags = [user_entry.split('\t') for user_entry in users.strip().split('\n')]
- users = dict()
- for user_parts in users_and_tags:
- users[user_parts[0]] = process_tags(user_parts[1]) if len(user_parts) > 1 else []
+ users = dict()
+ for user_parts in users_and_tags:
+ users[user_parts[0]] = process_tags(user_parts[1]) if len(user_parts) > 1 else []
self.existing_tags = users.get(self.username, list())
self.existing_permissions = self._get_permissions() if self.username in users else dict()
@@ -342,17 +463,48 @@ class RabbitMqUser(object):
def _get_permissions(self):
"""Get permissions of the user from RabbitMQ."""
- if self._version >= Version.StrictVersion('3.7.6'):
- permissions = json.loads(self._exec(['list_user_permissions', self.username, '--formatter', 'json']))
+ if self.login_host is not None:
+ try:
+ response = requests.get(self.get_permissions_api_url_builder(self.username),
+ auth=(self.login_user,
+ self.login_password))
+ except requests.exceptions.RequestException as exception:
+ msg = ("Error trying to request topic permissions "
+ "of the user %s info in rabbitmq.") % (self.username)
+ self.module.fail_json(
+ msg=msg,
+ exception=exception,
+ )
+
+ if response.ok or (response.status_code == 204):
+ permissions = list()
+ for permission in response.json():
+ permissions.append({
+ "vhost": permission.get('vhost'),
+ "configure": permission.get('configure'),
+ "write": permission.get('write'),
+ "read": permission.get('read')
+ })
+ elif response.status_code == 404:
+ return None
+ else:
+ self.module.fail_json(
+ msg="Error getting the user",
+ status=response.status_code,
+ details=response.text
+ )
else:
- output = self._exec(['list_user_permissions', self.username]).strip().split('\n')
- perms_out = [perm.split('\t') for perm in output if perm.strip()]
- # Filter out headers from the output of the command in case they are still present
- perms_out = [perm for perm in perms_out if perm != ["vhost", "configure", "write", "read"]]
+ if self._version >= Version.StrictVersion('3.7.6'):
+ permissions = json.loads(self._exec(['list_user_permissions', self.username, '--formatter', 'json']))
+ else:
+ output = self._exec(['list_user_permissions', self.username]).strip().split('\n')
+ perms_out = [perm.split('\t') for perm in output if perm.strip()]
+ # Filter out headers from the output of the command in case they are still present
+ perms_out = [perm for perm in perms_out if perm != ["vhost", "configure", "write", "read"]]
- permissions = list()
- for vhost, configure, write, read in perms_out:
- permissions.append(dict(vhost=vhost, configure=configure, write=write, read=read))
+ permissions = list()
+ for vhost, configure, write, read in perms_out:
+ permissions.append(dict(vhost=vhost, configure=configure, write=write, read=read))
if self.bulk_permissions:
return as_permission_dict(permissions)
@@ -361,58 +513,166 @@ class RabbitMqUser(object):
def _get_topic_permissions(self):
"""Get topic permissions of the user from RabbitMQ."""
- if self._version < Version.StrictVersion('3.7.0'):
- return dict()
- if self._version >= Version.StrictVersion('3.7.6'):
- permissions = json.loads(self._exec(['list_user_topic_permissions', self.username, '--formatter', 'json']))
+ if self.login_host is not None:
+ try:
+ response = requests.get(self.get_topic_permissions_api_url_builder(self.username),
+ auth=(self.login_user,
+ self.login_password))
+ except requests.exceptions.RequestException as exception:
+ msg = ("Error trying to request permissions "
+ "of the user %s info in rabbitmq.") % (self.username)
+ self.module.fail_json(
+ msg=msg,
+ exception=exception,
+ )
+
+ if response.ok or (response.status_code == 204):
+ permissions = list()
+ for permission in response.json():
+ permissions.append({
+ "vhost": permission.get('vhost'),
+ "exchange": permission.get('exchange'),
+ "write": permission.get('write'),
+ "read": permission.get('read')
+ })
+ return as_topic_permission_dict(permissions)
+ elif response.status_code == 404:
+ return None
+ else:
+ self.module.fail_json(
+ msg="Error getting the user",
+ status=response.status_code,
+ details=response.text
+ )
else:
- output = self._exec(['list_user_topic_permissions', self.username]).strip().split('\n')
- perms_out = [perm.split('\t') for perm in output if perm.strip()]
- permissions = list()
- for vhost, exchange, write, read in perms_out:
- permissions.append(dict(vhost=vhost, exchange=exchange, write=write, read=read))
- return as_topic_permission_dict(permissions)
+ if self._version < Version.StrictVersion('3.7.0'):
+ return dict()
+ if self._version >= Version.StrictVersion('3.7.6'):
+ permissions = json.loads(
+ self._exec(['list_user_topic_permissions', self.username, '--formatter', 'json']))
+ else:
+ output = self._exec(['list_user_topic_permissions', self.username]).strip().split('\n')
+ perms_out = [perm.split('\t') for perm in output if perm.strip()]
+ permissions = list()
+ for vhost, exchange, write, read in perms_out:
+ permissions.append(dict(vhost=vhost, exchange=exchange, write=write, read=read))
+ return as_topic_permission_dict(permissions)
def check_password(self):
"""Return `True` if the user can authenticate successfully."""
- rc, out, err = self._exec(['authenticate_user', self.username, self.password], check_rc=False)
- return rc == 0
+ if self.login_host is not None:
+ url = "%s://%s:%s/api/whoami" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port)
+ try:
+ response = requests.get(url, auth=(self.login_user, self.login_password))
+ except requests.exceptions.RequestException as exception:
+ msg = ("Error trying to request permissions "
+ "of the user %s info in rabbitmq.") % (self.username)
+ self.module.fail_json(
+ msg=msg,
+ exception=exception,
+ )
+
+ if response.ok or response.json().get('reason') == "Not management user":
+ return True
+ else:
+ return False
+ else:
+ rc, out, err = self._exec(['authenticate_user', self.username, self.password], check_rc=False)
+ return rc == 0
def add(self):
- self._exec(['add_user', self.username, self.password or ''])
- if not self.password:
- self._exec(['clear_password', self.username])
+ if self.login_host is not None:
+ data = {"password": self.password, "tags": self.treat_tags_for_api() or ""}
+ response = self.request_users_api('PUT', data)
+
+ if not response.ok or (response.status_code == 204):
+ msg = ("Error trying to create user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ self._exec(['add_user', self.username, self.password or ''])
+ if not self.password:
+ self._exec(['clear_password', self.username])
def delete(self):
- self._exec(['delete_user', self.username])
+ if self.login_host is not None:
+ response = self.request_users_api('DELETE')
+ if response.status_code != 204:
+ msg = ("Error trying to remove user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ self._exec(['delete_user', self.username])
def change_password(self):
- if self.password:
- self._exec(['change_password', self.username, self.password])
+ if self.login_host is not None:
+ data = {"password": self.password or "", "tags": self.tags or ""}
+ response = self.request_users_api('PUT', data)
+
+ if not response.ok or (response.status_code == 204):
+ msg = ("Error trying to set tags for the user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ self.module.fail_json(
+ msg="Error setting tags for the user",
+ status=response.status_code,
+ details=response.text
+ )
else:
- self._exec(['clear_password', self.username])
+ if self.password:
+ self._exec(['change_password', self.username, self.password])
+ else:
+ self._exec(['clear_password', self.username])
def set_tags(self):
- self._exec(['set_user_tags', self.username] + self.tags)
+ if self.login_host is not None:
+ data = {"password": self.password, "tags": self.treat_tags_for_api() or ""}
+ response = self.request_users_api('PUT', data)
+
+ if not response.status_code == 204:
+ msg = ("Error trying to set tags for the user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+
+ else:
+ self._exec(['set_user_tags', self.username] + self.tags)
def set_permissions(self):
permissions_to_add = list()
for vhost, permission_dict in self.permissions.items():
if permission_dict != self.existing_permissions.get(vhost, {}):
permissions_to_add.append(permission_dict)
-
permissions_to_clear = list()
for vhost in self.existing_permissions.keys():
if vhost not in self.permissions:
permissions_to_clear.append(vhost)
for vhost in permissions_to_clear:
- cmd = 'clear_permissions -p {vhost} {username}'.format(username=self.username, vhost=vhost)
- self._exec(cmd.split(' '))
+ if self.login_host is not None:
+ response = self.request_permissions_api('DELETE', vhost)
+ if response.status_code != 204:
+ msg = ("Error trying to remove permission from user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ cmd = 'clear_permissions -p {vhost} {username}'.format(username=self.username, vhost=vhost)
+ self._exec(cmd.split(' '))
for permissions in permissions_to_add:
- cmd = ('set_permissions -p {vhost} {username} {configure} {write} {read}'
- .format(username=self.username, **permissions))
- self._exec(cmd.split(' '))
+ if self.login_host is not None:
+ response = self.request_permissions_api('PUT', permissions.get('vhost'),
+ data=treat_permissions_for_api(permissions))
+ if response.status_code not in (201, 204):
+ msg = ("Error trying to add permission to user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ cmd = ('set_permissions -p {vhost} {username} {configure} {write} {read}'
+ .format(username=self.username, **permissions))
+ self._exec(cmd.split(' '))
self.existing_permissions = self._get_permissions()
def set_topic_permissions(self):
@@ -428,13 +688,28 @@ class RabbitMqUser(object):
for vhost_exchange in permissions_to_clear:
vhost, exchange = vhost_exchange
- cmd = ('clear_topic_permissions -p {vhost} {username} {exchange}'
- .format(username=self.username, vhost=vhost, exchange=exchange))
- self._exec(cmd.split(' '))
+ if self.login_host is not None:
+ response = self.request_topic_permissions_api('DELETE', vhost)
+ if response.status_code != 204:
+ msg = ("Error trying to remove topic permission from user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ cmd = ('clear_topic_permissions -p {vhost} {username} {exchange}'
+ .format(username=self.username, vhost=vhost, exchange=exchange))
+ self._exec(cmd.split(' '))
for permissions in permissions_to_add:
- cmd = ('set_topic_permissions -p {vhost} {username} {exchange} {write} {read}'
- .format(username=self.username, **permissions))
- self._exec(cmd.split(' '))
+ if self.login_host is not None:
+ response = self.request_topic_permissions_api('PUT', permissions.get('vhost'),
+ data=treat_topic_permissions_for_api(permissions))
+ if response.status_code not in (201, 204):
+ msg = ("Error trying to add topic permission to user %s in rabbitmq. "
+ "Status code '%s'.") % (self.username, response.status_code)
+ self.module.fail_json(msg=msg)
+ else:
+ cmd = ('set_topic_permissions -p {vhost} {username} {exchange} {write} {read}'
+ .format(username=self.username, **permissions))
+ self._exec(cmd.split(' '))
self.existing_topic_permissions = self._get_topic_permissions()
def has_tags_modifications(self):
@@ -446,6 +721,91 @@ class RabbitMqUser(object):
def has_topic_permissions_modifications(self):
return self.existing_topic_permissions != self.topic_permissions
+ def users_api_url_builder(self, username):
+ return "%s://%s:%s/api/users/%s" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port,
+ parse.quote(username, ""),
+ )
+
+ def get_permissions_api_url_builder(self, username):
+ return "%s://%s:%s/api/users/%s/permissions" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port,
+ username,
+ )
+
+ def get_topic_permissions_api_url_builder(self, username):
+ return "%s://%s:%s/api/users/%s/topic-permissions" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port,
+ username,
+ )
+
+ def permissions_api_url_builder(self, username, vhost):
+ if vhost is None or vhost == "/":
+ vhost = "%2F"
+ return "%s://%s:%s/api/permissions/%s/%s" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port,
+ vhost,
+ username,
+ )
+
+ def topic_permissions_api_url_builder(self, username, vhost):
+ if vhost is None or vhost == "/":
+ vhost = "%2F"
+ return "%s://%s:%s/api/topic-permissions/%s/%s" % (
+ self.login_protocol,
+ self.login_host,
+ self.login_port,
+ vhost,
+ username,
+ )
+
+ def treat_tags_for_api(self):
+ return ','.join(tag for tag in self.tags)
+
+ def request_users_api(self, method, data=None):
+ try:
+ response = requests.request(method, self.users_api_url_builder(self.username),
+ auth=(self.login_user, self.login_password), json=data)
+ except requests.exceptions.RequestException as exception:
+ msg = "Error in HTTP request (method %s) for user %s in rabbitmq." % (
+ method.lower(),
+ self.username,
+ )
+ self.module.fail_json(msg=msg, exception=exception)
+ return response
+
+ def request_permissions_api(self, method, vhost=None, data=None):
+ try:
+ response = requests.request(method, self.permissions_api_url_builder(self.username, vhost),
+ auth=(self.login_user, self.login_password), json=data)
+ except requests.exceptions.RequestException as exception:
+ msg = "Error in HTTP request (method %s) for user's permission %s in rabbitmq." % (
+ method.lower(),
+ self.username,
+ )
+ self.module.fail_json(msg=msg, exception=exception)
+ return response
+
+ def request_topic_permissions_api(self, method, vhost=None, data=None):
+ try:
+ response = requests.request(method, self.topic_permissions_api_url_builder(self.username, vhost),
+ auth=(self.login_user, self.login_password), json=data)
+ except requests.exceptions.RequestException as exception:
+ msg = "Error in HTTP request (method %s) for topic permission for user %s in rabbitmq." % (
+ method.lower(),
+ self.username,
+ )
+ self.module.fail_json(msg=msg, exception=exception)
+ return response
+
def main():
arg_spec = dict(
@@ -461,7 +821,12 @@ def main():
force=dict(default='no', type='bool'),
state=dict(default='present', choices=['present', 'absent']),
node=dict(default='rabbit'),
- update_password=dict(default='on_create', choices=['on_create', 'always'], no_log=False)
+ update_password=dict(default='on_create', choices=['on_create', 'always'], no_log=False),
+ login_protocol=dict(type="str", default="http", choices=["http", "https"]),
+ login_host=dict(type="str"),
+ login_port=dict(type="str", default="15672"),
+ login_user=dict(type="str", no_log=True),
+ login_password=dict(type="str", no_log=True)
)
module = AnsibleModule(
argument_spec=arg_spec,
@@ -481,6 +846,11 @@ def main():
state = module.params['state']
node = module.params['node']
update_password = module.params['update_password']
+ login_protocol = module.params['login_protocol']
+ login_host = module.params['login_host']
+ login_port = module.params['login_port']
+ login_user = module.params['login_user']
+ login_password = module.params['login_password']
if permissions:
vhosts = [permission.get('vhost', '/') for permission in permissions]
@@ -510,7 +880,7 @@ def main():
for permission in permissions:
if not permission['vhost']:
- module.fail_json(msg="Error parsing vhost permissions: You can't"
+ module.fail_json(msg="Error parsing vhost permissions: You can't "
"have an empty vhost when setting permissions")
for permission in topic_permissions:
@@ -524,7 +894,9 @@ def main():
rabbitmq_user = RabbitMqUser(module, username, password, tags, permissions,
topic_permissions, node,
- bulk_permissions=bulk_permissions)
+ bulk_permissions=bulk_permissions, login_protocol=login_protocol,
+ login_host=login_host, login_port=login_port, login_user=login_user,
+ login_password=login_password)
result = dict(changed=False, user=username, state=state)
if rabbitmq_user.get():
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml
index 740f89980..9808b9ec7 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/lookup_rabbitmq/tasks/main.yml
@@ -1,5 +1,5 @@
# Rabbitmq lookup
-- include: ubuntu.yml
- when:
+- include_tasks: ubuntu.yml
+ when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_release != 'trusty'
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml
index 740f89980..9808b9ec7 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_publish/tasks/main.yml
@@ -1,5 +1,5 @@
# Rabbitmq lookup
-- include: ubuntu.yml
- when:
+- include_tasks: ubuntu.yml
+ when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_release != 'trusty'
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml
index 740f89980..9808b9ec7 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_queue/tasks/main.yml
@@ -1,5 +1,5 @@
# Rabbitmq lookup
-- include: ubuntu.yml
- when:
+- include_tasks: ubuntu.yml
+ when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_release != 'trusty'
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml
index e03d4c7aa..9db0b6ee6 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/main.yml
@@ -5,6 +5,8 @@
- import_tasks: tests.yml
+ - import_tasks: tests_api.yml
+
- import_tasks: tests.yml
environment:
RABBITMQ_NODENAME: test
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml
new file mode 100644
index 000000000..51ded8778
--- /dev/null
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user/tasks/tests_api.yml
@@ -0,0 +1,131 @@
+---
+
+- name: Test add user
+ block:
+ - name: Add user
+ rabbitmq_user: user=joe password=changeme login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that user adding succeeds with a change
+ assert:
+ that:
+ - add_user.changed == true
+
+- name: Test add user idempotence
+ block:
+ - name: Add user
+ rabbitmq_user: user=joe password=changeme login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that user adding succeeds without a change
+ assert:
+ that:
+ - add_user.changed == false
+
+- name: Test change user permissions
+ block:
+ - name: Add user with permissions
+ rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that changing permissions succeeds with a change
+ assert:
+ that:
+ - add_user.changed == true
+
+- name: Test change user permissions idempotence
+ block:
+ - name: Add user with permissions
+ rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that changing permissions succeeds without a change
+ assert:
+ that:
+ - add_user.changed == false
+
+- name: Test change user topic permissions
+ block:
+ - name: Add user with topic permissions
+ rabbitmq_user:
+ user: joe
+ password: changeme
+ topic_permissions:
+ - vhost: /
+ exchange: amq.topic
+ read_priv: .*
+ write_priv: .*
+ login_user: guest
+ login_password: guest
+ login_host: 127.0.0.1
+ register: add_user
+
+ - name: Check that changing topic permissions succeeds with a change
+ assert:
+ that:
+ - add_user.changed == true
+
+- name: Test change user topic permissions idempotence
+ block:
+ - name: Add user with topic permissions
+ rabbitmq_user:
+ user: joe
+ password: changeme
+ topic_permissions:
+ - vhost: /
+ exchange: amq.topic
+ read_priv: .*
+ write_priv: .*
+ login_user: guest
+ login_password: guest
+ login_host: 127.0.0.1
+ register: add_user
+
+ - name: Check that changing topic permissions succeeds without a change
+ assert:
+ that:
+ - add_user.changed == false
+
+- name: Test add user tags
+ block:
+ - name: Add user with tags
+ rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=management,administrator login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that adding tags succeeds with a change
+ assert:
+ that:
+ - add_user.changed == true
+
+- name: Test add user tags idempotence
+ block:
+ - name: Add user with tags
+ rabbitmq_user: user=joe password=changeme vhost=/ configure_priv=.* read_priv=.* write_priv=.* tags=administrator,management login_user=guest login_password=guest login_host=127.0.0.1
+ register: add_user
+
+ - name: Check that adding tags succeeds without a change
+ assert:
+ that:
+ - add_user.changed == false
+
+- name: Test remove user
+ block:
+ - name: Remove user
+ rabbitmq_user: user=joe state=absent login_user=guest login_password=guest login_host=127.0.0.1
+ register: remove_user
+
+ - name: Check that user removing succeeds with a change
+ assert:
+ that:
+ - remove_user.changed == true
+
+- name: Test remove user idempotence
+ block:
+ - name: Remove user
+ rabbitmq_user: user=joe state=absent login_user=guest login_password=guest login_host=127.0.0.1
+ register: remove_user
+
+ - name: Check that user removing succeeds without a change
+ assert:
+ that:
+ - remove_user.changed == false
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml
index 740f89980..9808b9ec7 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_user_limits/tasks/main.yml
@@ -1,5 +1,5 @@
# Rabbitmq lookup
-- include: ubuntu.yml
- when:
+- include_tasks: ubuntu.yml
+ when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_release != 'trusty'
diff --git a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml
index 740f89980..9808b9ec7 100644
--- a/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml
+++ b/ansible_collections/community/rabbitmq/tests/integration/targets/rabbitmq_vhost_limits/tasks/main.yml
@@ -1,5 +1,5 @@
# Rabbitmq lookup
-- include: ubuntu.yml
- when:
+- include_tasks: ubuntu.yml
+ when:
- ansible_distribution == 'Ubuntu'
- ansible_distribution_release != 'trusty'
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.10.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.11.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.11.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.11.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt
index caf221794..8fd3dfc11 100644
--- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt
+++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.15.txt
@@ -1,2 +1,4 @@
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang
+plugins/module_utils/version.py pylint:unused-import
+tests/unit/compat/builtins.py pylint:unused-import
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt
new file mode 100644
index 000000000..fe7e62dfc
--- /dev/null
+++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.16.txt
@@ -0,0 +1,3 @@
+tests/utils/shippable/timing.py shebang
+plugins/module_utils/version.py pylint:unused-import
+tests/unit/compat/builtins.py pylint:unused-import
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt
new file mode 100644
index 000000000..fe7e62dfc
--- /dev/null
+++ b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.17.txt
@@ -0,0 +1,3 @@
+tests/utils/shippable/timing.py shebang
+plugins/module_utils/version.py pylint:unused-import
+tests/unit/compat/builtins.py pylint:unused-import
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/rabbitmq/tests/sanity/ignore-2.9.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/rabbitmq/tests/sanity/ignore.txt b/ansible_collections/community/rabbitmq/tests/sanity/ignore.txt
deleted file mode 100644
index caf221794..000000000
--- a/ansible_collections/community/rabbitmq/tests/sanity/ignore.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-tests/utils/shippable/check_matrix.py replace-urlopen
-tests/utils/shippable/timing.py shebang
diff --git a/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py b/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py
index 0972cd2e8..c7d018307 100644
--- a/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py
+++ b/ansible_collections/community/rabbitmq/tests/unit/compat/mock.py
@@ -64,8 +64,7 @@ if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
# newline that our naive format() added
data_as_list[-1] = data_as_list[-1][:-1]
- for line in data_as_list:
- yield line
+ yield from data_as_list
def mock_open(mock=None, read_data=''):
"""
@@ -93,8 +92,7 @@ if sys.version_info >= (3,) and sys.version_info < (3, 4, 4):
if handle.readline.return_value is not None:
while True:
yield handle.readline.return_value
- for line in _data:
- yield line
+ yield from _data
global file_spec
if file_spec is None:
diff --git a/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py b/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py
index 00a584127..e25731e03 100644
--- a/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py
+++ b/ansible_collections/community/rabbitmq/tests/unit/mock/loader.py
@@ -30,7 +30,7 @@ class DictDataLoader(DataLoader):
def __init__(self, file_mapping=None):
file_mapping = {} if file_mapping is None else file_mapping
- assert type(file_mapping) == dict
+ assert isinstance(file_mapping, dict)
super(DictDataLoader, self).__init__()
diff --git a/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh b/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh
index f9b187212..1f69f87e3 100755
--- a/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh
+++ b/ansible_collections/community/rabbitmq/tests/utils/shippable/shippable.sh
@@ -67,6 +67,7 @@ if [ "${SHIPPABLE_BUILD_ID:-}" ]; then
SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/rabbitmq"
mkdir -p "${TEST_DIR}"
+ # shellcheck disable=SC2153
cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
cd "${TEST_DIR}"
else