Blame koji-tags/library/koji_cg.py

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