|
|
|
@ -0,0 +1,260 @@
|
|
|
|
|
#!/usr/bin/python
|
|
|
|
|
#
|
|
|
|
|
# Copyright (c) 2017 OpenStack Foundation
|
|
|
|
|
# All Rights Reserved.
|
|
|
|
|
#
|
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
|
# not use this file except in compliance with the License. You may obtain
|
|
|
|
|
# a copy of the License at
|
|
|
|
|
#
|
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
#
|
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
|
# License for the specific language governing permissions and limitations
|
|
|
|
|
# under the License.
|
|
|
|
|
|
|
|
|
|
from __future__ import absolute_import
|
|
|
|
|
from __future__ import division
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
from copy import deepcopy
|
|
|
|
|
from fnmatch import fnmatch
|
|
|
|
|
import os
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
|
|
|
'status': ['preview'],
|
|
|
|
|
'supported_by': 'community'}
|
|
|
|
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
|
---
|
|
|
|
|
module: redhat_repository
|
|
|
|
|
short_description: Manage Red Hat repositories using the subscription-manager
|
|
|
|
|
command
|
|
|
|
|
description:
|
|
|
|
|
- Manage(List/Enable/Disable) Red Hat repositories to the Red Hat
|
|
|
|
|
Subscription Management entitlement platform using the
|
|
|
|
|
subscription-manager command.
|
|
|
|
|
version_added: '2.5'
|
|
|
|
|
author: Giovanni Sciortino (@giovannisciortino)
|
|
|
|
|
notes:
|
|
|
|
|
- In order to manage Red Hat repositories the system must be already
|
|
|
|
|
registered to Red Hat manually or using the ansible module
|
|
|
|
|
redhat_subscription.
|
|
|
|
|
- One option between name and list must be defined, both options in the
|
|
|
|
|
same task must not be defined.
|
|
|
|
|
|
|
|
|
|
requirements:
|
|
|
|
|
- subscription-manager
|
|
|
|
|
options:
|
|
|
|
|
state:
|
|
|
|
|
description:
|
|
|
|
|
- If state is equal to present or disabled, indicates the desired
|
|
|
|
|
repository state.
|
|
|
|
|
choices: [present, absent]
|
|
|
|
|
required: True
|
|
|
|
|
default: "present"
|
|
|
|
|
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
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
EXAMPLES = '''
|
|
|
|
|
- name: Enable a Red Hat repository
|
|
|
|
|
redhat_repository:
|
|
|
|
|
name: rhel-7-server-rpms
|
|
|
|
|
|
|
|
|
|
- name: Disable all Red Hat repositories
|
|
|
|
|
redhat_repository:
|
|
|
|
|
name: '*'
|
|
|
|
|
state: disabled
|
|
|
|
|
|
|
|
|
|
- name: Enable all repositories starting with rhel-6-server
|
|
|
|
|
redhat_repository:
|
|
|
|
|
name: rhel-6-server*
|
|
|
|
|
state: enabled
|
|
|
|
|
|
|
|
|
|
- name: Disable all repositories except rhel-7-server-rpms
|
|
|
|
|
redhat_repository:
|
|
|
|
|
name: "{{ item }}"
|
|
|
|
|
state: disabled
|
|
|
|
|
with_items: "{{
|
|
|
|
|
redhat_repository.repositories |
|
|
|
|
|
map(attribute='id') |
|
|
|
|
|
difference(['rhel-7-server-rpms']) }}"
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
RETURN = '''
|
|
|
|
|
repositories:
|
|
|
|
|
description:
|
|
|
|
|
- The list of Red Hat repositories with their states.
|
|
|
|
|
- When this module is used to change the repositories states, this list
|
|
|
|
|
contains the updated states after the changes.
|
|
|
|
|
returned: success
|
|
|
|
|
type: list
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_subscription_manager(module, arguments):
|
|
|
|
|
# Execute subuscription-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')
|
|
|
|
|
|
|
|
|
|
rc, out, err = module.run_command("%s %s" % (rhsm_bin,
|
|
|
|
|
" ".join(arguments)))
|
|
|
|
|
|
|
|
|
|
if rc == 1 and (err == 'The password you typed is invalid.\nPlease try ' +
|
|
|
|
|
'again.\n' or os.getuid() != 0):
|
|
|
|
|
module.fail_json(msg='The executable file subscription-manager must ' +
|
|
|
|
|
'be run using root privileges')
|
|
|
|
|
elif 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_str = r'Repo ID: (.*)'
|
|
|
|
|
repo_name_re_str = r'Repo Name: (.*)'
|
|
|
|
|
repo_url_re_str = r'Repo URL: (.*)'
|
|
|
|
|
repo_enabled_re_str = r'Enabled: (.*)'
|
|
|
|
|
|
|
|
|
|
repo_id = ''
|
|
|
|
|
repo_name = ''
|
|
|
|
|
repo_url = ''
|
|
|
|
|
repo_enabled = ''
|
|
|
|
|
|
|
|
|
|
repo_result = []
|
|
|
|
|
|
|
|
|
|
for line in out.split('\n'):
|
|
|
|
|
if line in skip_lines:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
repo_id_re = re.match(repo_id_re_str, line)
|
|
|
|
|
if repo_id_re:
|
|
|
|
|
repo_id = repo_id_re.group(1)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
repo_name_re = re.match(repo_name_re_str, line)
|
|
|
|
|
if repo_name_re:
|
|
|
|
|
repo_name = repo_name_re.group(1)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
repo_url_re = re.match(repo_url_re_str, line)
|
|
|
|
|
if repo_url_re:
|
|
|
|
|
repo_url = repo_url_re.group(1)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
repo_enabled_re = re.match(repo_enabled_re_str, line)
|
|
|
|
|
if repo_enabled_re:
|
|
|
|
|
repo_enabled = repo_enabled_re.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):
|
|
|
|
|
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
|
|
|
|
|
if state == 'enabled':
|
|
|
|
|
updated_repo_list[idx]['enabled'] = True
|
|
|
|
|
else:
|
|
|
|
|
updated_repo_list[idx]['enabled'] = 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 == 'disabled':
|
|
|
|
|
if repo['enabled']:
|
|
|
|
|
changed = True
|
|
|
|
|
diff_before += "Repository '%s' is enabled" % repo['id']
|
|
|
|
|
diff_after += "Repository '%s' is disabled" % repo['id']
|
|
|
|
|
results.append(
|
|
|
|
|
"Repository '%s' is disabled for this system" % repo['id'])
|
|
|
|
|
rhsm_arguments += ['--disable', repo['id']]
|
|
|
|
|
elif state == 'enabled':
|
|
|
|
|
if not repo['enabled']:
|
|
|
|
|
changed = True
|
|
|
|
|
diff_before += "Repository '%s' is disabled" % repo['id']
|
|
|
|
|
diff_after += "Repository '%s' is enabled" % repo['id']
|
|
|
|
|
results.append(
|
|
|
|
|
"Repository '%s' is enabled for this system" % repo['id'])
|
|
|
|
|
rhsm_arguments += ['--enable', repo['id']]
|
|
|
|
|
|
|
|
|
|
diff = {'before': diff_before + ' for this system\n',
|
|
|
|
|
'after': diff_after + ' for this system\n',
|
|
|
|
|
'before_header': "RHSM repositories",
|
|
|
|
|
'after_header': "RHSM repositories"}
|
|
|
|
|
|
|
|
|
|
if not module.check_mode:
|
|
|
|
|
rc, out, err = run_subscription_manager(module, rhsm_arguments)
|
|
|
|
|
results = out.split('\n')
|
|
|
|
|
module.exit_json(results=results, changed=changed,
|
|
|
|
|
repositories=updated_repo_list, diff=diff)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
module = AnsibleModule(
|
|
|
|
|
argument_spec=dict(
|
|
|
|
|
name=dict(type='list', required=True),
|
|
|
|
|
state=dict(choices=['enabled', 'disabled'], default='enabled'),
|
|
|
|
|
),
|
|
|
|
|
supports_check_mode=True,
|
|
|
|
|
)
|
|
|
|
|
name = module.params['name']
|
|
|
|
|
state = module.params['state']
|
|
|
|
|
|
|
|
|
|
repository_modify(module, state, name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|