Repository: ansible-collections/community.general

Issue:
redhat_subscription module is not idempotent when pool_ids are used
### Summary

When you provide some `pool_ids`, the module reports a change every time when it runs. The current entitements get removed and recreated afterwards:
```
- name: subscription | Ensure subscription
  community.general.redhat_subscription:
    state: present
    username: joe_user
    password: somepass
    pool_ids: 0123456789abcdef0123456789abcdef
```
Every run results in
```
TASK [rhsm : subscription | Ensure subscription] *************************
changed: [molecule-rhel-9.<my_company>]
```

### Issue Type

Bug Report

### Component Name

redhat_subscription

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.13.3]
  config file = None
  configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ansible/.local/lib/python3.10/site-packages/ansible
  ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/ansible/.local/bin/ansible
  python version = 3.10.6 (main, Aug 10 2022, 11:40:04) [GCC 11.3.0]
  jinja version = 3.0.3
  libyaml = True
```

### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general
Collection        Version
----------------- -------
community.general 5.5.0
```

### Configuration

```console (paste below)
$ ansible-config dump --only-changed
$
```


### OS / Environment

RHEL 9

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
---
- hosts: localhost
  tasks:
  - name: subscription | Ensure subscription
    community.general.redhat_subscription:
      state: present
      username: joe_user
      password: somepass
      pool_ids: 0123456789abcdef0123456789abcdef
```


### Expected Results

After the system has been registered and properly subscribed, the module should report no further change an keep the current entitlements untouched.

### Actual Results

```console (paste below)
TASK [rhsm : subscription | Ensure subscription] *************************
changed: [molecule-rhel-9.<my_company>]
```

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/packaging/os/redhat_subscription.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/packaging/os/redhat_subscription.py)

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @alikins @barnabycourt @kahowell
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/plugins/modules/packaging/os/redhat_subscription.py b/plugins/modules/packaging/os/redhat_subscription.py
--- a/plugins/modules/packaging/os/redhat_subscription.py
+++ b/plugins/modules/packaging/os/redhat_subscription.py
@@ -593,15 +593,22 @@ def update_subscriptions_by_pool_ids(self, pool_ids):
         consumed_pools = RhsmPools(self.module, consumed=True)
 
         existing_pools = {}
+        serials_to_remove = []
         for p in consumed_pools:
-            existing_pools[p.get_pool_id()] = p.QuantityUsed
+            pool_id = p.get_pool_id()
+            quantity_used = p.get_quantity_used()
+            existing_pools[pool_id] = quantity_used
+
+            quantity = pool_ids.get(pool_id, 0)
+            if quantity is not None and quantity != quantity_used:
+                serials_to_remove.append(p.Serial)
 
-        serials_to_remove = [p.Serial for p in consumed_pools if pool_ids.get(p.get_pool_id(), 0) != p.QuantityUsed]
         serials = self.unsubscribe(serials=serials_to_remove)
 
         missing_pools = {}
         for pool_id, quantity in sorted(pool_ids.items()):
-            if existing_pools.get(pool_id, 0) != quantity:
+            quantity_used = existing_pools.get(pool_id, 0)
+            if quantity is None and quantity_used == 0 or quantity not in (None, 0, quantity_used):
                 missing_pools[pool_id] = quantity
 
         self.subscribe_by_pool_ids(missing_pools)
@@ -635,6 +642,9 @@ def __str__(self):
     def get_pool_id(self):
         return getattr(self, 'PoolId', getattr(self, 'PoolID'))
 
+    def get_quantity_used(self):
+        return int(getattr(self, 'QuantityUsed'))
+
     def subscribe(self):
         args = "subscription-manager attach --pool %s" % self.get_pool_id()
         rc, stdout, stderr = self.module.run_command(args, check_rc=True)


Test patch: