mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
ffb9b6ff96
In case the "purge" option was enabled, the "repositories" element in the returned JSON was not updated with the repositories disabled by that option.
275 lines
9.9 KiB
Python
275 lines
9.9 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2017, Giovanni Sciortino (@giovannisciortino)
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: rhsm_repository
|
|
short_description: Manage RHSM repositories using the subscription-manager command
|
|
description:
|
|
- Manage (Enable/Disable) RHSM repositories to the Red Hat Subscription
|
|
Management entitlement platform using the C(subscription-manager) command.
|
|
author: Giovanni Sciortino (@giovannisciortino)
|
|
notes:
|
|
- In order to manage RHSM repositories the system must be already registered
|
|
to RHSM manually or using the Ansible M(community.general.redhat_subscription) module.
|
|
- It is possible to interact with C(subscription-manager) only as root,
|
|
so root permissions are required to successfully run this module.
|
|
|
|
requirements:
|
|
- subscription-manager
|
|
extends_documentation_fragment:
|
|
- community.general.attributes
|
|
attributes:
|
|
check_mode:
|
|
support: full
|
|
diff_mode:
|
|
support: full
|
|
options:
|
|
state:
|
|
description:
|
|
- If state is equal to present or disabled, indicates the desired
|
|
repository state.
|
|
- |
|
|
Please note that V(present) and V(absent) are deprecated, and will be
|
|
removed in community.general 10.0.0; please use V(enabled) and
|
|
V(disabled) instead.
|
|
choices: [present, enabled, absent, disabled]
|
|
default: "enabled"
|
|
type: str
|
|
name:
|
|
description:
|
|
- The ID of repositories to enable.
|
|
- To operate on several repositories this can accept a comma separated
|
|
list or a YAML list.
|
|
required: true
|
|
type: list
|
|
elements: str
|
|
purge:
|
|
description:
|
|
- Disable all currently enabled repositories that are not not specified in O(name).
|
|
Only set this to V(true) if passing in a list of repositories to the O(name) field.
|
|
Using this with C(loop) will most likely not have the desired result.
|
|
type: bool
|
|
default: false
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
- name: Enable a RHSM repository
|
|
community.general.rhsm_repository:
|
|
name: rhel-7-server-rpms
|
|
|
|
- name: Disable all RHSM repositories
|
|
community.general.rhsm_repository:
|
|
name: '*'
|
|
state: disabled
|
|
|
|
- name: Enable all repositories starting with rhel-6-server
|
|
community.general.rhsm_repository:
|
|
name: rhel-6-server*
|
|
state: enabled
|
|
|
|
- name: Disable all repositories except rhel-7-server-rpms
|
|
community.general.rhsm_repository:
|
|
name: rhel-7-server-rpms
|
|
purge: true
|
|
'''
|
|
|
|
RETURN = '''
|
|
repositories:
|
|
description:
|
|
- The list of RHSM repositories with their states.
|
|
- When this module is used to change the repository states, this list contains the updated states after the changes.
|
|
returned: success
|
|
type: list
|
|
'''
|
|
|
|
import re
|
|
import os
|
|
from fnmatch import fnmatch
|
|
from copy import deepcopy
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
|
def run_subscription_manager(module, arguments):
|
|
# Execute subscription-manager with arguments and manage common errors
|
|
rhsm_bin = module.get_bin_path('subscription-manager')
|
|
if not rhsm_bin:
|
|
module.fail_json(msg='The executable file subscription-manager was not found in PATH')
|
|
|
|
lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
|
|
rc, out, err = module.run_command("%s %s" % (rhsm_bin, " ".join(arguments)), environ_update=lang_env)
|
|
|
|
if rc == 0 and out == 'This system has no repositories available through subscriptions.\n':
|
|
module.fail_json(msg='This system has no repositories available through subscriptions')
|
|
elif rc == 1:
|
|
module.fail_json(msg='subscription-manager failed with the following error: %s' % err)
|
|
else:
|
|
return rc, out, err
|
|
|
|
|
|
def get_repository_list(module, list_parameter):
|
|
# Generate RHSM repository list and return a list of dict
|
|
if list_parameter == 'list_enabled':
|
|
rhsm_arguments = ['repos', '--list-enabled']
|
|
elif list_parameter == 'list_disabled':
|
|
rhsm_arguments = ['repos', '--list-disabled']
|
|
elif list_parameter == 'list':
|
|
rhsm_arguments = ['repos', '--list']
|
|
rc, out, err = run_subscription_manager(module, rhsm_arguments)
|
|
|
|
skip_lines = [
|
|
'+----------------------------------------------------------+',
|
|
' Available Repositories in /etc/yum.repos.d/redhat.repo'
|
|
]
|
|
repo_id_re = re.compile(r'Repo ID:\s+(.*)')
|
|
repo_name_re = re.compile(r'Repo Name:\s+(.*)')
|
|
repo_url_re = re.compile(r'Repo URL:\s+(.*)')
|
|
repo_enabled_re = re.compile(r'Enabled:\s+(.*)')
|
|
|
|
repo_id = ''
|
|
repo_name = ''
|
|
repo_url = ''
|
|
repo_enabled = ''
|
|
|
|
repo_result = []
|
|
for line in out.splitlines():
|
|
if line == '' or line in skip_lines:
|
|
continue
|
|
|
|
repo_id_match = repo_id_re.match(line)
|
|
if repo_id_match:
|
|
repo_id = repo_id_match.group(1)
|
|
continue
|
|
|
|
repo_name_match = repo_name_re.match(line)
|
|
if repo_name_match:
|
|
repo_name = repo_name_match.group(1)
|
|
continue
|
|
|
|
repo_url_match = repo_url_re.match(line)
|
|
if repo_url_match:
|
|
repo_url = repo_url_match.group(1)
|
|
continue
|
|
|
|
repo_enabled_match = repo_enabled_re.match(line)
|
|
if repo_enabled_match:
|
|
repo_enabled = repo_enabled_match.group(1)
|
|
|
|
repo = {
|
|
"id": repo_id,
|
|
"name": repo_name,
|
|
"url": repo_url,
|
|
"enabled": True if repo_enabled == '1' else False
|
|
}
|
|
|
|
repo_result.append(repo)
|
|
|
|
return repo_result
|
|
|
|
|
|
def repository_modify(module, state, name, purge=False):
|
|
name = set(name)
|
|
current_repo_list = get_repository_list(module, 'list')
|
|
updated_repo_list = deepcopy(current_repo_list)
|
|
matched_existing_repo = {}
|
|
for repoid in name:
|
|
matched_existing_repo[repoid] = []
|
|
for idx, repo in enumerate(current_repo_list):
|
|
if fnmatch(repo['id'], repoid):
|
|
matched_existing_repo[repoid].append(repo)
|
|
# Update current_repo_list to return it as result variable
|
|
updated_repo_list[idx]['enabled'] = True if state == 'enabled' else False
|
|
|
|
changed = False
|
|
results = []
|
|
diff_before = ""
|
|
diff_after = ""
|
|
rhsm_arguments = ['repos']
|
|
|
|
for repoid in matched_existing_repo:
|
|
if len(matched_existing_repo[repoid]) == 0:
|
|
results.append("%s is not a valid repository ID" % repoid)
|
|
module.fail_json(results=results, msg="%s is not a valid repository ID" % repoid)
|
|
for repo in matched_existing_repo[repoid]:
|
|
if state in ['disabled', 'absent']:
|
|
if repo['enabled']:
|
|
changed = True
|
|
diff_before += "Repository '%s' is enabled for this system\n" % repo['id']
|
|
diff_after += "Repository '%s' is disabled for this system\n" % repo['id']
|
|
results.append("Repository '%s' is disabled for this system" % repo['id'])
|
|
rhsm_arguments += ['--disable', repo['id']]
|
|
elif state in ['enabled', 'present']:
|
|
if not repo['enabled']:
|
|
changed = True
|
|
diff_before += "Repository '%s' is disabled for this system\n" % repo['id']
|
|
diff_after += "Repository '%s' is enabled for this system\n" % repo['id']
|
|
results.append("Repository '%s' is enabled for this system" % repo['id'])
|
|
rhsm_arguments += ['--enable', repo['id']]
|
|
|
|
# Disable all enabled repos on the system that are not in the task and not
|
|
# marked as disabled by the task
|
|
if purge:
|
|
enabled_repo_ids = set(repo['id'] for repo in updated_repo_list if repo['enabled'])
|
|
matched_repoids_set = set(matched_existing_repo.keys())
|
|
difference = enabled_repo_ids.difference(matched_repoids_set)
|
|
if len(difference) > 0:
|
|
for repoid in difference:
|
|
changed = True
|
|
diff_before.join("Repository '{repoid}'' is enabled for this system\n".format(repoid=repoid))
|
|
diff_after.join("Repository '{repoid}' is disabled for this system\n".format(repoid=repoid))
|
|
results.append("Repository '{repoid}' is disabled for this system".format(repoid=repoid))
|
|
rhsm_arguments.extend(['--disable', repoid])
|
|
for updated_repo in updated_repo_list:
|
|
if updated_repo['id'] in difference:
|
|
updated_repo['enabled'] = False
|
|
|
|
diff = {'before': diff_before,
|
|
'after': diff_after,
|
|
'before_header': "RHSM repositories",
|
|
'after_header': "RHSM repositories"}
|
|
|
|
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)
|
|
|
|
|
|
def main():
|
|
module = AnsibleModule(
|
|
argument_spec=dict(
|
|
name=dict(type='list', elements='str', required=True),
|
|
state=dict(choices=['enabled', 'disabled', 'present', 'absent'], default='enabled'),
|
|
purge=dict(type='bool', default=False),
|
|
),
|
|
supports_check_mode=True,
|
|
)
|
|
|
|
if os.getuid() != 0:
|
|
module.fail_json(
|
|
msg="Interacting with subscription-manager requires root permissions ('become: true')"
|
|
)
|
|
|
|
name = module.params['name']
|
|
state = module.params['state']
|
|
purge = module.params['purge']
|
|
|
|
if state in ['present', 'absent']:
|
|
replacement = 'enabled' if state == 'present' else 'disabled'
|
|
module.deprecate(
|
|
'state=%s is deprecated; please use state=%s instead' % (state, replacement),
|
|
version='10.0.0',
|
|
collection_name='community.general',
|
|
)
|
|
|
|
repository_modify(module, state, name, purge)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|