2020-03-09 10:11:07 +01:00
|
|
|
#!/usr/bin/python
|
2021-08-08 10:40:22 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
2020-03-09 10:11:07 +01:00
|
|
|
|
2022-08-05 12:28:29 +02:00
|
|
|
# Copyright (c) Vincent Van de Kussen
|
|
|
|
# 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
|
2020-03-09 10:11:07 +01:00
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
|
|
---
|
|
|
|
module: rhn_channel
|
|
|
|
short_description: Adds or removes Red Hat software channels
|
|
|
|
description:
|
|
|
|
- Adds or removes Red Hat software channels.
|
|
|
|
author:
|
2023-02-20 17:30:26 +01:00
|
|
|
- Vincent Van der Kussen (@vincentvdk)
|
2020-03-09 10:11:07 +01:00
|
|
|
notes:
|
|
|
|
- This module fetches the system id from RHN.
|
2023-02-20 17:30:26 +01:00
|
|
|
extends_documentation_fragment:
|
|
|
|
- community.general.attributes
|
|
|
|
attributes:
|
|
|
|
check_mode:
|
|
|
|
support: none
|
|
|
|
diff_mode:
|
|
|
|
support: none
|
2020-03-09 10:11:07 +01:00
|
|
|
options:
|
|
|
|
name:
|
|
|
|
description:
|
|
|
|
- Name of the software channel.
|
|
|
|
required: true
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
sysname:
|
|
|
|
description:
|
|
|
|
- Name of the system as it is known in RHN/Satellite.
|
|
|
|
required: true
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
state:
|
|
|
|
description:
|
|
|
|
- Whether the channel should be present or not, taking action if the state is different from what is stated.
|
|
|
|
default: present
|
2020-11-13 13:41:11 +01:00
|
|
|
choices: [ present, absent ]
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
url:
|
|
|
|
description:
|
|
|
|
- The full URL to the RHN/Satellite API.
|
|
|
|
required: true
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
user:
|
|
|
|
description:
|
|
|
|
- RHN/Satellite login.
|
|
|
|
required: true
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-09 10:11:07 +01:00
|
|
|
password:
|
|
|
|
description:
|
|
|
|
- RHN/Satellite password.
|
2020-06-26 15:17:11 +02:00
|
|
|
aliases: [pwd]
|
2020-03-09 10:11:07 +01:00
|
|
|
required: true
|
2020-06-26 15:17:11 +02:00
|
|
|
type: str
|
2020-03-31 08:47:20 +02:00
|
|
|
validate_certs:
|
|
|
|
description:
|
|
|
|
- If C(False), SSL certificates will not be validated.
|
|
|
|
- This should only set to C(False) when used on self controlled sites
|
|
|
|
using self-signed certificates, and you are absolutely sure that nobody
|
|
|
|
can modify traffic between the module and the site.
|
|
|
|
type: bool
|
|
|
|
default: true
|
2020-06-13 15:01:19 +02:00
|
|
|
version_added: '0.2.0'
|
2023-05-09 19:30:19 +02:00
|
|
|
deprecated:
|
|
|
|
removed_in: 10.0.0
|
|
|
|
why: |
|
|
|
|
RHN hosted at redhat.com was discontinued years ago, and Spacewalk 5
|
|
|
|
(which uses RHN) is EOL since 2020, May 31st; while this module could
|
|
|
|
work on Uyuni / SUSE Manager (fork of Spacewalk 5), we have not heard
|
|
|
|
about anyone using it in those setups.
|
|
|
|
alternative: |
|
|
|
|
Contact the community.general maintainers to report the usage of this
|
|
|
|
module, and potentially step up to maintain it.
|
2020-03-09 10:11:07 +01:00
|
|
|
'''
|
|
|
|
|
|
|
|
EXAMPLES = '''
|
2020-05-15 12:27:06 +02:00
|
|
|
- name: Add a Red Hat software channel
|
2020-07-13 21:50:31 +02:00
|
|
|
community.general.rhn_channel:
|
2020-03-09 10:11:07 +01:00
|
|
|
name: rhel-x86_64-server-v2vwin-6
|
|
|
|
sysname: server01
|
|
|
|
url: https://rhn.redhat.com/rpc/api
|
|
|
|
user: rhnuser
|
|
|
|
password: guessme
|
|
|
|
delegate_to: localhost
|
|
|
|
'''
|
|
|
|
|
2020-03-31 08:47:20 +02:00
|
|
|
import ssl
|
2021-06-26 23:59:11 +02:00
|
|
|
from ansible.module_utils.common.text.converters import to_text
|
2020-03-09 10:11:07 +01:00
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
from ansible.module_utils.six.moves import xmlrpc_client
|
|
|
|
|
|
|
|
|
|
|
|
def get_systemid(client, session, sysname):
|
|
|
|
systems = client.system.listUserSystems(session)
|
|
|
|
for system in systems:
|
|
|
|
if system.get('name') == sysname:
|
|
|
|
idres = system.get('id')
|
|
|
|
idd = int(idres)
|
|
|
|
return idd
|
|
|
|
|
|
|
|
|
|
|
|
def subscribe_channels(channelname, client, session, sysname, sys_id):
|
|
|
|
channels = base_channels(client, session, sys_id)
|
|
|
|
channels.append(channelname)
|
|
|
|
return client.system.setChildChannels(session, sys_id, channels)
|
|
|
|
|
|
|
|
|
|
|
|
def unsubscribe_channels(channelname, client, session, sysname, sys_id):
|
|
|
|
channels = base_channels(client, session, sys_id)
|
|
|
|
channels.remove(channelname)
|
|
|
|
return client.system.setChildChannels(session, sys_id, channels)
|
|
|
|
|
|
|
|
|
|
|
|
def base_channels(client, session, sys_id):
|
|
|
|
basechan = client.channel.software.listSystemChannels(session, sys_id)
|
|
|
|
try:
|
|
|
|
chans = [item['label'] for item in basechan]
|
|
|
|
except KeyError:
|
|
|
|
chans = [item['channel_label'] for item in basechan]
|
|
|
|
return chans
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
|
|
module = AnsibleModule(
|
|
|
|
argument_spec=dict(
|
|
|
|
state=dict(type='str', default='present', choices=['present', 'absent']),
|
|
|
|
name=dict(type='str', required=True),
|
|
|
|
sysname=dict(type='str', required=True),
|
|
|
|
url=dict(type='str', required=True),
|
|
|
|
user=dict(type='str', required=True),
|
|
|
|
password=dict(type='str', required=True, aliases=['pwd'], no_log=True),
|
2020-03-31 08:47:20 +02:00
|
|
|
validate_certs=dict(type='bool', default=True),
|
2020-03-09 10:11:07 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
state = module.params['state']
|
|
|
|
channelname = module.params['name']
|
|
|
|
systname = module.params['sysname']
|
|
|
|
saturl = module.params['url']
|
|
|
|
user = module.params['user']
|
|
|
|
password = module.params['password']
|
2020-03-31 08:47:20 +02:00
|
|
|
validate_certs = module.params['validate_certs']
|
|
|
|
|
|
|
|
ssl_context = None
|
|
|
|
if not validate_certs:
|
|
|
|
try: # Python 2.7.9 and newer
|
|
|
|
ssl_context = ssl.create_unverified_context()
|
|
|
|
except AttributeError: # Legacy Python that doesn't verify HTTPS certificates by default
|
2021-01-03 11:15:51 +01:00
|
|
|
ssl_context = ssl._create_unverified_context()
|
2020-03-31 08:47:20 +02:00
|
|
|
else: # Python 2.7.8 and older
|
|
|
|
ssl._create_default_https_context = ssl._create_unverified_https_context
|
2020-03-09 10:11:07 +01:00
|
|
|
|
|
|
|
# initialize connection
|
2020-03-31 08:47:20 +02:00
|
|
|
if ssl_context:
|
|
|
|
client = xmlrpc_client.ServerProxy(saturl, context=ssl_context)
|
|
|
|
else:
|
|
|
|
client = xmlrpc_client.Server(saturl)
|
|
|
|
|
2020-03-09 10:11:07 +01:00
|
|
|
try:
|
|
|
|
session = client.auth.login(user, password)
|
|
|
|
except Exception as e:
|
|
|
|
module.fail_json(msg="Unable to establish session with Satellite server: %s " % to_text(e))
|
|
|
|
|
|
|
|
if not session:
|
|
|
|
module.fail_json(msg="Failed to establish session with Satellite server.")
|
|
|
|
|
|
|
|
# get systemid
|
|
|
|
try:
|
|
|
|
sys_id = get_systemid(client, session, systname)
|
|
|
|
except Exception as e:
|
|
|
|
module.fail_json(msg="Unable to get system id: %s " % to_text(e))
|
|
|
|
|
|
|
|
if not sys_id:
|
|
|
|
module.fail_json(msg="Failed to get system id.")
|
|
|
|
|
|
|
|
# get channels for system
|
|
|
|
try:
|
|
|
|
chans = base_channels(client, session, sys_id)
|
|
|
|
except Exception as e:
|
|
|
|
module.fail_json(msg="Unable to get channel information: %s " % to_text(e))
|
|
|
|
|
|
|
|
try:
|
|
|
|
if state == 'present':
|
|
|
|
if channelname in chans:
|
|
|
|
module.exit_json(changed=False, msg="Channel %s already exists" % channelname)
|
|
|
|
else:
|
|
|
|
subscribe_channels(channelname, client, session, systname, sys_id)
|
|
|
|
module.exit_json(changed=True, msg="Channel %s added" % channelname)
|
|
|
|
|
|
|
|
if state == 'absent':
|
|
|
|
if channelname not in chans:
|
|
|
|
module.exit_json(changed=False, msg="Not subscribed to channel %s." % channelname)
|
|
|
|
else:
|
|
|
|
unsubscribe_channels(channelname, client, session, systname, sys_id)
|
|
|
|
module.exit_json(changed=True, msg="Channel %s removed" % channelname)
|
|
|
|
except Exception as e:
|
|
|
|
module.fail_json(msg='Unable to %s channel (%s): %s' % ('add' if state == 'present' else 'remove', channelname, to_text(e)))
|
|
|
|
finally:
|
|
|
|
client.auth.logout(session)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|