Lay groundwork for selection input methods

Change-Id: I9adf771ce5fe72efeb3225b6c2329ada479ca4d3
This commit is contained in:
Sam Doran 2017-12-18 18:22:44 -05:00 committed by Emilien Macchi
parent a4d2420e60
commit d4e81a1af9
8 changed files with 268 additions and 2 deletions

View File

@ -18,6 +18,7 @@ Role Variables
| `rhn_password` | No default | Red Hat Portal password. |
| `rhn_activation_key` | No default | Red Hat Portal Activation Key. |
| `rhn_org_id` | No default | Red Hat Portal Organization Identifier. |
| `rhsub_method` | `portal` | Set to `portal` or `satellite` depending on where you are registering. |
| `rhsub_state` | `enable` | Whether to enable or disable a Red Hat subscription. |
| `rhsub_autosubscribe` | `yes` | Whether or not to autosubscibe to available repositories. |
| `rhsub_repos` | `[undefined]` | If defined, the list of repositories to enable or disable. See `defaults/main.yml` for examples. |

View File

@ -6,6 +6,7 @@
rhsub_state: present # present or absent
rhsub_autosubscribe: True
rhsub_method: portal # portal or satellite
# rhsub_repos:
# - name: rhel-7-server-extras-rpms # wildcard or repo name

View File

@ -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()

View File

@ -3,7 +3,7 @@ galaxy_info:
description: "Manage Red Hat subscription and repositories."
company:
license: Apache 2.0
min_ansible_version: 2.3
min_ansible_version: 2.4
platforms:
- name: EL

View File

@ -36,3 +36,7 @@
tags:
- rhsub
- rhsub_repos
- import_tasks: "{{ rhsub_method }}.yml"
tags:
- rhsub

0
tasks/portal.yml Normal file
View File

0
tasks/satellite.yml Normal file
View File

2
tests/Vagrantfile vendored
View File

@ -12,7 +12,7 @@ Vagrant.configure(2) do |config|
end
# RHEL 7
config.vm.define "rhel7" do |rhel7|
config.vm.define "rhsub-rhel7" do |rhel7|
rhel7.vm.box = "samdoran/rhel7"
rhel7.vm.hostname = "rhsub-rhel7"
config.vm.provider "virtualbox" do |vbox|