We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
rhsm_repository is really slow
##### SUMMARY
Using rhsm_repository is really slow, making it annoying to use a playback that uses it.
(copied from https://github.com/ansible/ansible/issues/69722)

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
rhsm_repository

##### ANSIBLE VERSION
```
ansible 2.9.9
  config file = /root/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```

##### CONFIGURATION
```
[defaults]
stdout_callback = yaml
force_handlers = True
```

##### OS / ENVIRONMENT
Ansible machine:
Target machine: RHEL 8


##### STEPS TO REPRODUCE
```yaml
- name: enable Red Hat CodeReady repo
  rhsm_repository:
    name: codeready-builder-for-rhel-8-x86_64-rpms
  when: ansible_facts['distribution'] == "RedHat" and ansible_facts['distribution_major_version'] == "8"
```

##### EXPECTED RESULTS
The above task should complete in a short time, at least when the repository is already enabled.


##### ACTUAL RESULTS
You have time to get coffee whilst your playbook runs.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/modules/packaging/os/rhsm_repository.py`
Content:
```
1 #!/usr/bin/python
2 
3 # Copyright: (c) 2017, Giovanni Sciortino (@giovannisciortino)
4 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5 
6 from __future__ import absolute_import, division, print_function
7 __metaclass__ = type
8 
9 DOCUMENTATION = '''
10 ---
11 module: rhsm_repository
12 short_description: Manage RHSM repositories using the subscription-manager command
13 description:
14   - Manage (Enable/Disable) RHSM repositories to the Red Hat Subscription
15     Management entitlement platform using the C(subscription-manager) command.
16 author: Giovanni Sciortino (@giovannisciortino)
17 notes:
18   - In order to manage RHSM repositories the system must be already registered
19     to RHSM manually or using the Ansible C(redhat_subscription) module.
20 
21 requirements:
22   - subscription-manager
23 options:
24   state:
25     description:
26       - If state is equal to present or disabled, indicates the desired
27         repository state.
28     choices: [present, enabled, absent, disabled]
29     required: True
30     default: "present"
31   name:
32     description:
33       - The ID of repositories to enable.
34       - To operate on several repositories this can accept a comma separated
35         list or a YAML list.
36     required: True
37   purge:
38     description:
39       - Disable all currently enabled repositories that are not not specified in C(name).
40         Only set this to C(True) if passing in a list of repositories to the C(name) field.
41         Using this with C(loop) will most likely not have the desired result.
42     type: bool
43     default: False
44 '''
45 
46 EXAMPLES = '''
47 - name: Enable a RHSM repository
48   rhsm_repository:
49     name: rhel-7-server-rpms
50 
51 - name: Disable all RHSM repositories
52   rhsm_repository:
53     name: '*'
54     state: disabled
55 
56 - name: Enable all repositories starting with rhel-6-server
57   rhsm_repository:
58     name: rhel-6-server*
59     state: enabled
60 
61 - name: Disable all repositories except rhel-7-server-rpms
62   rhsm_repository:
63     name: rhel-7-server-rpms
64     purge: True
65 '''
66 
67 RETURN = '''
68 repositories:
69   description:
70     - The list of RHSM repositories with their states.
71     - When this module is used to change the repository states, this list contains the updated states after the changes.
72   returned: success
73   type: list
74 '''
75 
76 import re
77 import os
78 from fnmatch import fnmatch
79 from copy import deepcopy
80 from ansible.module_utils.basic import AnsibleModule
81 
82 
83 def run_subscription_manager(module, arguments):
84     # Execute subscription-manager with arguments and manage common errors
85     rhsm_bin = module.get_bin_path('subscription-manager')
86     if not rhsm_bin:
87         module.fail_json(msg='The executable file subscription-manager was not found in PATH')
88 
89     lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
90     rc, out, err = module.run_command("%s %s" % (rhsm_bin, " ".join(arguments)), environ_update=lang_env)
91 
92     if rc == 1 and (err == 'The password you typed is invalid.\nPlease try again.\n' or os.getuid() != 0):
93         module.fail_json(msg='The executable file subscription-manager must be run using root privileges')
94     elif rc == 0 and out == 'This system has no repositories available through subscriptions.\n':
95         module.fail_json(msg='This system has no repositories available through subscriptions')
96     elif rc == 1:
97         module.fail_json(msg='subscription-manager failed with the following error: %s' % err)
98     else:
99         return rc, out, err
100 
101 
102 def get_repository_list(module, list_parameter):
103     # Generate RHSM repository list and return a list of dict
104     if list_parameter == 'list_enabled':
105         rhsm_arguments = ['repos', '--list-enabled']
106     elif list_parameter == 'list_disabled':
107         rhsm_arguments = ['repos', '--list-disabled']
108     elif list_parameter == 'list':
109         rhsm_arguments = ['repos', '--list']
110     rc, out, err = run_subscription_manager(module, rhsm_arguments)
111 
112     skip_lines = [
113         '+----------------------------------------------------------+',
114         '    Available Repositories in /etc/yum.repos.d/redhat.repo'
115     ]
116     repo_id_re = re.compile(r'Repo ID:\s+(.*)')
117     repo_name_re = re.compile(r'Repo Name:\s+(.*)')
118     repo_url_re = re.compile(r'Repo URL:\s+(.*)')
119     repo_enabled_re = re.compile(r'Enabled:\s+(.*)')
120 
121     repo_id = ''
122     repo_name = ''
123     repo_url = ''
124     repo_enabled = ''
125 
126     repo_result = []
127     for line in out.splitlines():
128         if line == '' or line in skip_lines:
129             continue
130 
131         repo_id_match = repo_id_re.match(line)
132         if repo_id_match:
133             repo_id = repo_id_match.group(1)
134             continue
135 
136         repo_name_match = repo_name_re.match(line)
137         if repo_name_match:
138             repo_name = repo_name_match.group(1)
139             continue
140 
141         repo_url_match = repo_url_re.match(line)
142         if repo_url_match:
143             repo_url = repo_url_match.group(1)
144             continue
145 
146         repo_enabled_match = repo_enabled_re.match(line)
147         if repo_enabled_match:
148             repo_enabled = repo_enabled_match.group(1)
149 
150             repo = {
151                 "id": repo_id,
152                 "name": repo_name,
153                 "url": repo_url,
154                 "enabled": True if repo_enabled == '1' else False
155             }
156 
157             repo_result.append(repo)
158 
159     return repo_result
160 
161 
162 def repository_modify(module, state, name, purge=False):
163     name = set(name)
164     current_repo_list = get_repository_list(module, 'list')
165     updated_repo_list = deepcopy(current_repo_list)
166     matched_existing_repo = {}
167     for repoid in name:
168         matched_existing_repo[repoid] = []
169         for idx, repo in enumerate(current_repo_list):
170             if fnmatch(repo['id'], repoid):
171                 matched_existing_repo[repoid].append(repo)
172                 # Update current_repo_list to return it as result variable
173                 updated_repo_list[idx]['enabled'] = True if state == 'enabled' else False
174 
175     changed = False
176     results = []
177     diff_before = ""
178     diff_after = ""
179     rhsm_arguments = ['repos']
180 
181     for repoid in matched_existing_repo:
182         if len(matched_existing_repo[repoid]) == 0:
183             results.append("%s is not a valid repository ID" % repoid)
184             module.fail_json(results=results, msg="%s is not a valid repository ID" % repoid)
185         for repo in matched_existing_repo[repoid]:
186             if state in ['disabled', 'absent']:
187                 if repo['enabled']:
188                     changed = True
189                     diff_before += "Repository '%s' is enabled for this system\n" % repo['id']
190                     diff_after += "Repository '%s' is disabled for this system\n" % repo['id']
191                 results.append("Repository '%s' is disabled for this system" % repo['id'])
192                 rhsm_arguments += ['--disable', repo['id']]
193             elif state in ['enabled', 'present']:
194                 if not repo['enabled']:
195                     changed = True
196                     diff_before += "Repository '%s' is disabled for this system\n" % repo['id']
197                     diff_after += "Repository '%s' is enabled for this system\n" % repo['id']
198                 results.append("Repository '%s' is enabled for this system" % repo['id'])
199                 rhsm_arguments += ['--enable', repo['id']]
200 
201     # Disable all enabled repos on the system that are not in the task and not
202     # marked as disabled by the task
203     if purge:
204         enabled_repo_ids = set(repo['id'] for repo in updated_repo_list if repo['enabled'])
205         matched_repoids_set = set(matched_existing_repo.keys())
206         difference = enabled_repo_ids.difference(matched_repoids_set)
207         if len(difference) > 0:
208             for repoid in difference:
209                 changed = True
210                 diff_before.join("Repository '{repoid}'' is enabled for this system\n".format(repoid=repoid))
211                 diff_after.join("Repository '{repoid}' is disabled for this system\n".format(repoid=repoid))
212                 results.append("Repository '{repoid}' is disabled for this system".format(repoid=repoid))
213                 rhsm_arguments.extend(['--disable', repoid])
214 
215     diff = {'before': diff_before,
216             'after': diff_after,
217             'before_header': "RHSM repositories",
218             'after_header': "RHSM repositories"}
219 
220     if not module.check_mode:
221         rc, out, err = run_subscription_manager(module, rhsm_arguments)
222         results = out.splitlines()
223     module.exit_json(results=results, changed=changed, repositories=updated_repo_list, diff=diff)
224 
225 
226 def main():
227     module = AnsibleModule(
228         argument_spec=dict(
229             name=dict(type='list', required=True),
230             state=dict(choices=['enabled', 'disabled', 'present', 'absent'], default='enabled'),
231             purge=dict(type='bool', default=False),
232         ),
233         supports_check_mode=True,
234     )
235     name = module.params['name']
236     state = module.params['state']
237     purge = module.params['purge']
238 
239     repository_modify(module, state, name, purge)
240 
241 
242 if __name__ == '__main__':
243     main()
244
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugins/modules/packaging/os/rhsm_repository.py b/plugins/modules/packaging/os/rhsm_repository.py
--- a/plugins/modules/packaging/os/rhsm_repository.py
+++ b/plugins/modules/packaging/os/rhsm_repository.py
@@ -217,7 +217,7 @@
             'before_header': "RHSM repositories",
             'after_header': "RHSM repositories"}
 
-    if not module.check_mode:
+    if not module.check_mode and changed:
         rc, out, err = run_subscription_manager(module, rhsm_arguments)
         results = out.splitlines()
     module.exit_json(results=results, changed=changed, repositories=updated_repo_list, diff=diff)

{"golden_diff": "diff --git a/plugins/modules/packaging/os/rhsm_repository.py b/plugins/modules/packaging/os/rhsm_repository.py\n--- a/plugins/modules/packaging/os/rhsm_repository.py\n+++ b/plugins/modules/packaging/os/rhsm_repository.py\n@@ -217,7 +217,7 @@\n             'before_header': \"RHSM repositories\",\n             'after_header': \"RHSM repositories\"}\n \n-    if not module.check_mode:\n+    if not module.check_mode and changed:\n         rc, out, err = run_subscription_manager(module, rhsm_arguments)\n         results = out.splitlines()\n     module.exit_json(results=results, changed=changed, repositories=updated_repo_list, diff=diff)\n", "issue": "rhsm_repository is really slow\n##### SUMMARY\r\nUsing rhsm_repository is really slow, making it annoying to use a playback that uses it.\r\n(copied from https://github.com/ansible/ansible/issues/69722)\r\n\r\n##### ISSUE TYPE\r\n- Bug Report\r\n\r\n##### COMPONENT NAME\r\nrhsm_repository\r\n\r\n##### ANSIBLE VERSION\r\n```\r\nansible 2.9.9\r\n  config file = /root/ansible/ansible.cfg\r\n  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /usr/lib/python2.7/site-packages/ansible\r\n  executable location = /usr/bin/ansible\r\n  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]\r\n```\r\n\r\n##### CONFIGURATION\r\n```\r\n[defaults]\r\nstdout_callback = yaml\r\nforce_handlers = True\r\n```\r\n\r\n##### OS / ENVIRONMENT\r\nAnsible machine:\r\nTarget machine: RHEL 8\r\n\r\n\r\n##### STEPS TO REPRODUCE\r\n```yaml\r\n- name: enable Red Hat CodeReady repo\r\n  rhsm_repository:\r\n    name: codeready-builder-for-rhel-8-x86_64-rpms\r\n  when: ansible_facts['distribution'] == \"RedHat\" and ansible_facts['distribution_major_version'] == \"8\"\r\n```\r\n\r\n##### EXPECTED RESULTS\r\nThe above task should complete in a short time, at least when the repository is already enabled.\r\n\r\n\r\n##### ACTUAL RESULTS\r\nYou have time to get coffee whilst your playbook runs.\n", "before_files": [{"content": "#!/usr/bin/python\n\n# Copyright: (c) 2017, Giovanni Sciortino (@giovannisciortino)\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\nDOCUMENTATION = '''\n---\nmodule: rhsm_repository\nshort_description: Manage RHSM repositories using the subscription-manager command\ndescription:\n  - Manage (Enable/Disable) RHSM repositories to the Red Hat Subscription\n    Management entitlement platform using the C(subscription-manager) command.\nauthor: Giovanni Sciortino (@giovannisciortino)\nnotes:\n  - In order to manage RHSM repositories the system must be already registered\n    to RHSM manually or using the Ansible C(redhat_subscription) module.\n\nrequirements:\n  - subscription-manager\noptions:\n  state:\n    description:\n      - If state is equal to present or disabled, indicates the desired\n        repository state.\n    choices: [present, enabled, absent, disabled]\n    required: True\n    default: \"present\"\n  name:\n    description:\n      - The ID of repositories to enable.\n      - To operate on several repositories this can accept a comma separated\n        list or a YAML list.\n    required: True\n  purge:\n    description:\n      - Disable all currently enabled repositories that are not not specified in C(name).\n        Only set this to C(True) if passing in a list of repositories to the C(name) field.\n        Using this with C(loop) will most likely not have the desired result.\n    type: bool\n    default: False\n'''\n\nEXAMPLES = '''\n- name: Enable a RHSM repository\n  rhsm_repository:\n    name: rhel-7-server-rpms\n\n- name: Disable all RHSM repositories\n  rhsm_repository:\n    name: '*'\n    state: disabled\n\n- name: Enable all repositories starting with rhel-6-server\n  rhsm_repository:\n    name: rhel-6-server*\n    state: enabled\n\n- name: Disable all repositories except rhel-7-server-rpms\n  rhsm_repository:\n    name: rhel-7-server-rpms\n    purge: True\n'''\n\nRETURN = '''\nrepositories:\n  description:\n    - The list of RHSM repositories with their states.\n    - When this module is used to change the repository states, this list contains the updated states after the changes.\n  returned: success\n  type: list\n'''\n\nimport re\nimport os\nfrom fnmatch import fnmatch\nfrom copy import deepcopy\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef run_subscription_manager(module, arguments):\n    # Execute subscription-manager with arguments and manage common errors\n    rhsm_bin = module.get_bin_path('subscription-manager')\n    if not rhsm_bin:\n        module.fail_json(msg='The executable file subscription-manager was not found in PATH')\n\n    lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')\n    rc, out, err = module.run_command(\"%s %s\" % (rhsm_bin, \" \".join(arguments)), environ_update=lang_env)\n\n    if rc == 1 and (err == 'The password you typed is invalid.\\nPlease try again.\\n' or os.getuid() != 0):\n        module.fail_json(msg='The executable file subscription-manager must be run using root privileges')\n    elif rc == 0 and out == 'This system has no repositories available through subscriptions.\\n':\n        module.fail_json(msg='This system has no repositories available through subscriptions')\n    elif rc == 1:\n        module.fail_json(msg='subscription-manager failed with the following error: %s' % err)\n    else:\n        return rc, out, err\n\n\ndef get_repository_list(module, list_parameter):\n    # Generate RHSM repository list and return a list of dict\n    if list_parameter == 'list_enabled':\n        rhsm_arguments = ['repos', '--list-enabled']\n    elif list_parameter == 'list_disabled':\n        rhsm_arguments = ['repos', '--list-disabled']\n    elif list_parameter == 'list':\n        rhsm_arguments = ['repos', '--list']\n    rc, out, err = run_subscription_manager(module, rhsm_arguments)\n\n    skip_lines = [\n        '+----------------------------------------------------------+',\n        '    Available Repositories in /etc/yum.repos.d/redhat.repo'\n    ]\n    repo_id_re = re.compile(r'Repo ID:\\s+(.*)')\n    repo_name_re = re.compile(r'Repo Name:\\s+(.*)')\n    repo_url_re = re.compile(r'Repo URL:\\s+(.*)')\n    repo_enabled_re = re.compile(r'Enabled:\\s+(.*)')\n\n    repo_id = ''\n    repo_name = ''\n    repo_url = ''\n    repo_enabled = ''\n\n    repo_result = []\n    for line in out.splitlines():\n        if line == '' or line in skip_lines:\n            continue\n\n        repo_id_match = repo_id_re.match(line)\n        if repo_id_match:\n            repo_id = repo_id_match.group(1)\n            continue\n\n        repo_name_match = repo_name_re.match(line)\n        if repo_name_match:\n            repo_name = repo_name_match.group(1)\n            continue\n\n        repo_url_match = repo_url_re.match(line)\n        if repo_url_match:\n            repo_url = repo_url_match.group(1)\n            continue\n\n        repo_enabled_match = repo_enabled_re.match(line)\n        if repo_enabled_match:\n            repo_enabled = repo_enabled_match.group(1)\n\n            repo = {\n                \"id\": repo_id,\n                \"name\": repo_name,\n                \"url\": repo_url,\n                \"enabled\": True if repo_enabled == '1' else False\n            }\n\n            repo_result.append(repo)\n\n    return repo_result\n\n\ndef repository_modify(module, state, name, purge=False):\n    name = set(name)\n    current_repo_list = get_repository_list(module, 'list')\n    updated_repo_list = deepcopy(current_repo_list)\n    matched_existing_repo = {}\n    for repoid in name:\n        matched_existing_repo[repoid] = []\n        for idx, repo in enumerate(current_repo_list):\n            if fnmatch(repo['id'], repoid):\n                matched_existing_repo[repoid].append(repo)\n                # Update current_repo_list to return it as result variable\n                updated_repo_list[idx]['enabled'] = True if state == 'enabled' else False\n\n    changed = False\n    results = []\n    diff_before = \"\"\n    diff_after = \"\"\n    rhsm_arguments = ['repos']\n\n    for repoid in matched_existing_repo:\n        if len(matched_existing_repo[repoid]) == 0:\n            results.append(\"%s is not a valid repository ID\" % repoid)\n            module.fail_json(results=results, msg=\"%s is not a valid repository ID\" % repoid)\n        for repo in matched_existing_repo[repoid]:\n            if state in ['disabled', 'absent']:\n                if repo['enabled']:\n                    changed = True\n                    diff_before += \"Repository '%s' is enabled for this system\\n\" % repo['id']\n                    diff_after += \"Repository '%s' is disabled for this system\\n\" % repo['id']\n                results.append(\"Repository '%s' is disabled for this system\" % repo['id'])\n                rhsm_arguments += ['--disable', repo['id']]\n            elif state in ['enabled', 'present']:\n                if not repo['enabled']:\n                    changed = True\n                    diff_before += \"Repository '%s' is disabled for this system\\n\" % repo['id']\n                    diff_after += \"Repository '%s' is enabled for this system\\n\" % repo['id']\n                results.append(\"Repository '%s' is enabled for this system\" % repo['id'])\n                rhsm_arguments += ['--enable', repo['id']]\n\n    # Disable all enabled repos on the system that are not in the task and not\n    # marked as disabled by the task\n    if purge:\n        enabled_repo_ids = set(repo['id'] for repo in updated_repo_list if repo['enabled'])\n        matched_repoids_set = set(matched_existing_repo.keys())\n        difference = enabled_repo_ids.difference(matched_repoids_set)\n        if len(difference) > 0:\n            for repoid in difference:\n                changed = True\n                diff_before.join(\"Repository '{repoid}'' is enabled for this system\\n\".format(repoid=repoid))\n                diff_after.join(\"Repository '{repoid}' is disabled for this system\\n\".format(repoid=repoid))\n                results.append(\"Repository '{repoid}' is disabled for this system\".format(repoid=repoid))\n                rhsm_arguments.extend(['--disable', repoid])\n\n    diff = {'before': diff_before,\n            'after': diff_after,\n            'before_header': \"RHSM repositories\",\n            'after_header': \"RHSM repositories\"}\n\n    if not module.check_mode:\n        rc, out, err = run_subscription_manager(module, rhsm_arguments)\n        results = out.splitlines()\n    module.exit_json(results=results, changed=changed, repositories=updated_repo_list, diff=diff)\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec=dict(\n            name=dict(type='list', required=True),\n            state=dict(choices=['enabled', 'disabled', 'present', 'absent'], default='enabled'),\n            purge=dict(type='bool', default=False),\n        ),\n        supports_check_mode=True,\n    )\n    name = module.params['name']\n    state = module.params['state']\n    purge = module.params['purge']\n\n    repository_modify(module, state, name, purge)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/packaging/os/rhsm_repository.py"}], "after_files": [{"content": "#!/usr/bin/python\n\n# Copyright: (c) 2017, Giovanni Sciortino (@giovannisciortino)\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\nDOCUMENTATION = '''\n---\nmodule: rhsm_repository\nshort_description: Manage RHSM repositories using the subscription-manager command\ndescription:\n  - Manage (Enable/Disable) RHSM repositories to the Red Hat Subscription\n    Management entitlement platform using the C(subscription-manager) command.\nauthor: Giovanni Sciortino (@giovannisciortino)\nnotes:\n  - In order to manage RHSM repositories the system must be already registered\n    to RHSM manually or using the Ansible C(redhat_subscription) module.\n\nrequirements:\n  - subscription-manager\noptions:\n  state:\n    description:\n      - If state is equal to present or disabled, indicates the desired\n        repository state.\n    choices: [present, enabled, absent, disabled]\n    required: True\n    default: \"present\"\n  name:\n    description:\n      - The ID of repositories to enable.\n      - To operate on several repositories this can accept a comma separated\n        list or a YAML list.\n    required: True\n  purge:\n    description:\n      - Disable all currently enabled repositories that are not not specified in C(name).\n        Only set this to C(True) if passing in a list of repositories to the C(name) field.\n        Using this with C(loop) will most likely not have the desired result.\n    type: bool\n    default: False\n'''\n\nEXAMPLES = '''\n- name: Enable a RHSM repository\n  rhsm_repository:\n    name: rhel-7-server-rpms\n\n- name: Disable all RHSM repositories\n  rhsm_repository:\n    name: '*'\n    state: disabled\n\n- name: Enable all repositories starting with rhel-6-server\n  rhsm_repository:\n    name: rhel-6-server*\n    state: enabled\n\n- name: Disable all repositories except rhel-7-server-rpms\n  rhsm_repository:\n    name: rhel-7-server-rpms\n    purge: True\n'''\n\nRETURN = '''\nrepositories:\n  description:\n    - The list of RHSM repositories with their states.\n    - When this module is used to change the repository states, this list contains the updated states after the changes.\n  returned: success\n  type: list\n'''\n\nimport re\nimport os\nfrom fnmatch import fnmatch\nfrom copy import deepcopy\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef run_subscription_manager(module, arguments):\n    # Execute subscription-manager with arguments and manage common errors\n    rhsm_bin = module.get_bin_path('subscription-manager')\n    if not rhsm_bin:\n        module.fail_json(msg='The executable file subscription-manager was not found in PATH')\n\n    lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')\n    rc, out, err = module.run_command(\"%s %s\" % (rhsm_bin, \" \".join(arguments)), environ_update=lang_env)\n\n    if rc == 1 and (err == 'The password you typed is invalid.\\nPlease try again.\\n' or os.getuid() != 0):\n        module.fail_json(msg='The executable file subscription-manager must be run using root privileges')\n    elif rc == 0 and out == 'This system has no repositories available through subscriptions.\\n':\n        module.fail_json(msg='This system has no repositories available through subscriptions')\n    elif rc == 1:\n        module.fail_json(msg='subscription-manager failed with the following error: %s' % err)\n    else:\n        return rc, out, err\n\n\ndef get_repository_list(module, list_parameter):\n    # Generate RHSM repository list and return a list of dict\n    if list_parameter == 'list_enabled':\n        rhsm_arguments = ['repos', '--list-enabled']\n    elif list_parameter == 'list_disabled':\n        rhsm_arguments = ['repos', '--list-disabled']\n    elif list_parameter == 'list':\n        rhsm_arguments = ['repos', '--list']\n    rc, out, err = run_subscription_manager(module, rhsm_arguments)\n\n    skip_lines = [\n        '+----------------------------------------------------------+',\n        '    Available Repositories in /etc/yum.repos.d/redhat.repo'\n    ]\n    repo_id_re = re.compile(r'Repo ID:\\s+(.*)')\n    repo_name_re = re.compile(r'Repo Name:\\s+(.*)')\n    repo_url_re = re.compile(r'Repo URL:\\s+(.*)')\n    repo_enabled_re = re.compile(r'Enabled:\\s+(.*)')\n\n    repo_id = ''\n    repo_name = ''\n    repo_url = ''\n    repo_enabled = ''\n\n    repo_result = []\n    for line in out.splitlines():\n        if line == '' or line in skip_lines:\n            continue\n\n        repo_id_match = repo_id_re.match(line)\n        if repo_id_match:\n            repo_id = repo_id_match.group(1)\n            continue\n\n        repo_name_match = repo_name_re.match(line)\n        if repo_name_match:\n            repo_name = repo_name_match.group(1)\n            continue\n\n        repo_url_match = repo_url_re.match(line)\n        if repo_url_match:\n            repo_url = repo_url_match.group(1)\n            continue\n\n        repo_enabled_match = repo_enabled_re.match(line)\n        if repo_enabled_match:\n            repo_enabled = repo_enabled_match.group(1)\n\n            repo = {\n                \"id\": repo_id,\n                \"name\": repo_name,\n                \"url\": repo_url,\n                \"enabled\": True if repo_enabled == '1' else False\n            }\n\n            repo_result.append(repo)\n\n    return repo_result\n\n\ndef repository_modify(module, state, name, purge=False):\n    name = set(name)\n    current_repo_list = get_repository_list(module, 'list')\n    updated_repo_list = deepcopy(current_repo_list)\n    matched_existing_repo = {}\n    for repoid in name:\n        matched_existing_repo[repoid] = []\n        for idx, repo in enumerate(current_repo_list):\n            if fnmatch(repo['id'], repoid):\n                matched_existing_repo[repoid].append(repo)\n                # Update current_repo_list to return it as result variable\n                updated_repo_list[idx]['enabled'] = True if state == 'enabled' else False\n\n    changed = False\n    results = []\n    diff_before = \"\"\n    diff_after = \"\"\n    rhsm_arguments = ['repos']\n\n    for repoid in matched_existing_repo:\n        if len(matched_existing_repo[repoid]) == 0:\n            results.append(\"%s is not a valid repository ID\" % repoid)\n            module.fail_json(results=results, msg=\"%s is not a valid repository ID\" % repoid)\n        for repo in matched_existing_repo[repoid]:\n            if state in ['disabled', 'absent']:\n                if repo['enabled']:\n                    changed = True\n                    diff_before += \"Repository '%s' is enabled for this system\\n\" % repo['id']\n                    diff_after += \"Repository '%s' is disabled for this system\\n\" % repo['id']\n                results.append(\"Repository '%s' is disabled for this system\" % repo['id'])\n                rhsm_arguments += ['--disable', repo['id']]\n            elif state in ['enabled', 'present']:\n                if not repo['enabled']:\n                    changed = True\n                    diff_before += \"Repository '%s' is disabled for this system\\n\" % repo['id']\n                    diff_after += \"Repository '%s' is enabled for this system\\n\" % repo['id']\n                results.append(\"Repository '%s' is enabled for this system\" % repo['id'])\n                rhsm_arguments += ['--enable', repo['id']]\n\n    # Disable all enabled repos on the system that are not in the task and not\n    # marked as disabled by the task\n    if purge:\n        enabled_repo_ids = set(repo['id'] for repo in updated_repo_list if repo['enabled'])\n        matched_repoids_set = set(matched_existing_repo.keys())\n        difference = enabled_repo_ids.difference(matched_repoids_set)\n        if len(difference) > 0:\n            for repoid in difference:\n                changed = True\n                diff_before.join(\"Repository '{repoid}'' is enabled for this system\\n\".format(repoid=repoid))\n                diff_after.join(\"Repository '{repoid}' is disabled for this system\\n\".format(repoid=repoid))\n                results.append(\"Repository '{repoid}' is disabled for this system\".format(repoid=repoid))\n                rhsm_arguments.extend(['--disable', repoid])\n\n    diff = {'before': diff_before,\n            'after': diff_after,\n            'before_header': \"RHSM repositories\",\n            'after_header': \"RHSM repositories\"}\n\n    if not module.check_mode and changed:\n        rc, out, err = run_subscription_manager(module, rhsm_arguments)\n        results = out.splitlines()\n    module.exit_json(results=results, changed=changed, repositories=updated_repo_list, diff=diff)\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec=dict(\n            name=dict(type='list', required=True),\n            state=dict(choices=['enabled', 'disabled', 'present', 'absent'], default='enabled'),\n            purge=dict(type='bool', default=False),\n        ),\n        supports_check_mode=True,\n    )\n    name = module.params['name']\n    state = module.params['state']\n    purge = module.params['purge']\n\n    repository_modify(module, state, name, purge)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/packaging/os/rhsm_repository.py"}]}