|
|
6e61fb |
#!/usr/bin/python
|
|
|
6e61fb |
import sys
|
|
|
6e61fb |
from ansible.module_utils.basic import AnsibleModule
|
|
|
6e61fb |
from ansible.module_utils import common_koji
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
ANSIBLE_METADATA = {
|
|
|
6e61fb |
'metadata_version': '1.0',
|
|
|
6e61fb |
'status': ['preview'],
|
|
|
6e61fb |
'supported_by': 'community'
|
|
|
6e61fb |
}
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
DOCUMENTATION = '''
|
|
|
6e61fb |
---
|
|
|
6e61fb |
module: koji_cg
|
|
|
6e61fb |
|
|
|
6e61fb |
short_description: Create and manage Koji content generators
|
|
|
6e61fb |
description:
|
|
|
6e61fb |
- This module can grant or revoke access to a `content generator
|
|
|
6e61fb |
<https://docs.pagure.org/koji/content_generators/>`_ for a user account.
|
|
|
6e61fb |
- Your Koji Hub must be version 1.19 or newer in order to use the new
|
|
|
6e61fb |
`listCGs <https://pagure.io/koji/pull-request/1160>`_ RPC.
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
options:
|
|
|
6e61fb |
name:
|
|
|
6e61fb |
description:
|
|
|
6e61fb |
- The name of the Koji content generator.
|
|
|
6e61fb |
- 'Example: "debian".'
|
|
|
6e61fb |
required: true
|
|
|
6e61fb |
user:
|
|
|
6e61fb |
description:
|
|
|
6e61fb |
- The name of the Koji user account.
|
|
|
6e61fb |
- This user account must already exist in Koji's database. For example,
|
|
|
6e61fb |
you may run an authenticated "koji hello" command to create the
|
|
|
6e61fb |
account database entry.
|
|
|
6e61fb |
- 'Example: "cguser".'
|
|
|
6e61fb |
required: true
|
|
|
6e61fb |
requirements:
|
|
|
6e61fb |
- "python >= 2.7"
|
|
|
6e61fb |
- "koji"
|
|
|
6e61fb |
'''
|
|
|
6e61fb |
|
|
|
6e61fb |
EXAMPLES = '''
|
|
|
6e61fb |
- name: Grant a user access to a content generator.
|
|
|
6e61fb |
hosts: localhost
|
|
|
6e61fb |
tasks:
|
|
|
6e61fb |
- name: Grant access to the rcm/debbuild account
|
|
|
6e61fb |
koji_cg:
|
|
|
6e61fb |
name: debian
|
|
|
6e61fb |
user: rcm/debbuild
|
|
|
6e61fb |
state: present
|
|
|
6e61fb |
'''
|
|
|
6e61fb |
|
|
|
6e61fb |
RETURN = ''' # '''
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
class UnknownCGsError(Exception):
|
|
|
6e61fb |
""" We cannot know what CGs are present """
|
|
|
6e61fb |
pass
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def list_cgs(session):
|
|
|
6e61fb |
""" Return the result of listCGs, or raise UnknownCGsError """
|
|
|
6e61fb |
koji_profile = sys.modules[session.__module__]
|
|
|
6e61fb |
try:
|
|
|
6e61fb |
return session.listCGs()
|
|
|
6e61fb |
except koji_profile.GenericError as e:
|
|
|
6e61fb |
if str(e) == 'Invalid method: listCGs':
|
|
|
6e61fb |
# Kojihub before version 1.20 will raise this error.
|
|
|
6e61fb |
raise UnknownCGsError
|
|
|
6e61fb |
raise
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def ensure_cg(session, user, name, state, cgs, check_mode):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Ensure that a content generator and user is present or absent.
|
|
|
6e61fb |
|
|
|
6e61fb |
:param session: koji ClientSession
|
|
|
6e61fb |
:param str user: koji user name
|
|
|
6e61fb |
:param str name: content generator name
|
|
|
6e61fb |
:param str state: "present" or "absent"
|
|
|
6e61fb |
:param dict cgs: existing content generators and users
|
|
|
6e61fb |
:param bool check_mode: if True, show what would happen, but don't do it.
|
|
|
6e61fb |
:returns: result
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
result = {'changed': False}
|
|
|
6e61fb |
if state == 'present':
|
|
|
6e61fb |
if name not in cgs or user not in cgs[name]['users']:
|
|
|
6e61fb |
if not check_mode:
|
|
|
6e61fb |
common_koji.ensure_logged_in(session)
|
|
|
6e61fb |
session.grantCGAccess(user, name, create=True)
|
|
|
6e61fb |
result['changed'] = True
|
|
|
6e61fb |
elif state == 'absent':
|
|
|
6e61fb |
if name in cgs and user in cgs[name]['users']:
|
|
|
6e61fb |
if not check_mode:
|
|
|
6e61fb |
common_koji.ensure_logged_in(session)
|
|
|
6e61fb |
session.revokeCGAccess(user, name)
|
|
|
6e61fb |
result['changed'] = True
|
|
|
6e61fb |
return result
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def ensure_unknown_cg(session, user, name, state):
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
Ensure that a content generator and user is present or absent.
|
|
|
6e61fb |
|
|
|
6e61fb |
This method is for older versions of Koji where we do not have the listCGs
|
|
|
6e61fb |
RPC. This method does not support check_mode.
|
|
|
6e61fb |
|
|
|
6e61fb |
:param session: koji ClientSession
|
|
|
6e61fb |
:param str user: koji user name
|
|
|
6e61fb |
:param str name: content generator name
|
|
|
6e61fb |
:param str state: "present" or "absent"
|
|
|
6e61fb |
:returns: result
|
|
|
6e61fb |
"""
|
|
|
6e61fb |
result = {'changed': False}
|
|
|
6e61fb |
koji_profile = sys.modules[session.__module__]
|
|
|
6e61fb |
common_koji.ensure_logged_in(session)
|
|
|
6e61fb |
if state == 'present':
|
|
|
6e61fb |
# The "grant" method will at least raise an error if the permission
|
|
|
6e61fb |
# was already granted, so we can set the "changed" result based on
|
|
|
6e61fb |
# that.
|
|
|
6e61fb |
try:
|
|
|
6e61fb |
session.grantCGAccess(user, name, create=True)
|
|
|
6e61fb |
result['changed'] = True
|
|
|
6e61fb |
except koji_profile.GenericError as e:
|
|
|
6e61fb |
if 'User already has access to content generator' not in str(e):
|
|
|
6e61fb |
raise
|
|
|
6e61fb |
elif state == 'absent':
|
|
|
6e61fb |
# There's no indication whether this changed anything, so we're going
|
|
|
6e61fb |
# to be pessimistic and say we're always changing it.
|
|
|
6e61fb |
session.revokeCGAccess(user, name)
|
|
|
6e61fb |
result['changed'] = True
|
|
|
6e61fb |
return result
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def run_module():
|
|
|
6e61fb |
module_args = dict(
|
|
|
6e61fb |
koji=dict(type='str', required=False),
|
|
|
6e61fb |
name=dict(type='str', required=True),
|
|
|
6e61fb |
user=dict(type='str', required=True),
|
|
|
6e61fb |
state=dict(type='str', choices=[
|
|
|
6e61fb |
'present', 'absent'], required=False, default='present'),
|
|
|
6e61fb |
)
|
|
|
6e61fb |
module = AnsibleModule(
|
|
|
6e61fb |
argument_spec=module_args,
|
|
|
6e61fb |
supports_check_mode=True
|
|
|
6e61fb |
)
|
|
|
6e61fb |
|
|
|
6e61fb |
if not common_koji.HAS_KOJI:
|
|
|
6e61fb |
module.fail_json(msg='koji is required for this module')
|
|
|
6e61fb |
|
|
|
6e61fb |
check_mode = module.check_mode
|
|
|
6e61fb |
params = module.params
|
|
|
6e61fb |
profile = params['koji']
|
|
|
6e61fb |
name = params['name']
|
|
|
6e61fb |
user = params['user']
|
|
|
6e61fb |
state = params['state']
|
|
|
6e61fb |
|
|
|
6e61fb |
session = common_koji.get_session(profile)
|
|
|
6e61fb |
|
|
|
6e61fb |
try:
|
|
|
6e61fb |
cgs = list_cgs(session)
|
|
|
6e61fb |
result = ensure_cg(session, user, name, state, cgs, check_mode)
|
|
|
6e61fb |
except UnknownCGsError:
|
|
|
6e61fb |
if check_mode:
|
|
|
6e61fb |
msg = 'check mode does not work without listCGs'
|
|
|
6e61fb |
result = {'changed': False, 'msg': msg}
|
|
|
6e61fb |
else:
|
|
|
6e61fb |
result = ensure_unknown_cg(session, user, name, state)
|
|
|
6e61fb |
|
|
|
6e61fb |
module.exit_json(**result)
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
def main():
|
|
|
6e61fb |
run_module()
|
|
|
6e61fb |
|
|
|
6e61fb |
|
|
|
6e61fb |
if __name__ == '__main__':
|
|
|
6e61fb |
main()
|