bstinson / centos / releng

Forked from centos/releng 3 years ago
Clone

Blame koji-tags/library/koji_tag.py

6e61fb
#!/usr/bin/python
6e61fb
from ansible.module_utils.basic import AnsibleModule
6e61fb
from collections import defaultdict
6e61fb
from ansible.module_utils import common_koji
6e61fb
from ansible.module_utils.six import string_types
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_tag
6e61fb
6e61fb
short_description: Create and manage Koji tags
6e61fb
description:
6e61fb
   - Create and manage Koji tags
6e61fb
options:
6e61fb
   name:
6e61fb
     description:
6e61fb
       - The name of the Koji tag to create and manage.
6e61fb
     required: true
6e61fb
   inheritance:
6e61fb
     description:
6e61fb
       - How to set inheritance. what happens when it's unset.
6e61fb
   external_repos:
6e61fb
     description:
6e61fb
       - list of Koji external repos to set for this tag. Each element of the
6e61fb
         list should have a "repo" (the external repo name) and "priority"
6e61fb
         (integer).
6e61fb
   packages:
6e61fb
     description:
6e61fb
       - dict of package owners and the a lists of packages each owner
6e61fb
         maintains.
6e61fb
   groups:
6e61fb
     description:
6e61fb
       - A tag's "groups" tell Koji what packages will be present in the
6e61fb
         tag's buildroot. For example, the "build" group defines the packages
6e61fb
         that Koji will put into a "build" task's buildroot. You may set other
6e61fb
         package groups on a tag as well, like "srpm-build" or
6e61fb
         "applicance-build".
6e61fb
       - This should be a dict of groups and packages to set for this tag.
6e61fb
         Each dict key will be the name of the group. Each dict value should
6e61fb
         be a list of package names to include in the comps for this group.
6e61fb
       - If a group or package defined in this field is already applicable for
6e61fb
         a tag due to inheritance, Koji will not allow it to be added to the
6e61fb
         tag, but will instead silently ignore it. Conversely, groups and
6e61fb
         packages that are inherited in this field are not removed if they are
6e61fb
         left unspecified. Therefore, this field will only have an effect if it
6e61fb
         includes groups and packages that are unique to this tag (i.e., not
6e61fb
         inherited).
6e61fb
       - This does not support advanced comps group operations, like
6e61fb
         configuring extra options on groups, or blocking packages in groups.
6e61fb
         If you need that level of control over comps groups, you will need
6e61fb
         to import a full comps XML file, outside of this Ansible module.
6e61fb
   arches:
6e61fb
     description:
6e61fb
       - space-separated string of arches this Koji tag supports.
6e61fb
       - Note, the order in which you specify architectures does matter in a
6e61fb
         few subtle cases. For example, the SRPM that Koji includes in the
6e61fb
         build is the one built on the first arch in this list. Likewise,
6e61fb
         rpmdiff compares RPMs built on the first arch with RPMs built on
6e61fb
         other arches.
6e61fb
   perm:
6e61fb
     description:
6e61fb
       - permission (string or int) for this Koji tag.
6e61fb
   locked:
6e61fb
     description:
6e61fb
       - whether to lock this tag or not.
6e61fb
     choices: [true, false]
6e61fb
     default: false
6e61fb
   maven_support:
6e61fb
     description:
6e61fb
       - whether Maven repos should be generated for the tag.
6e61fb
     choices: [true, false]
6e61fb
     default: false
6e61fb
   maven_include_all:
6e61fb
     description:
6e61fb
       - include every build in this tag (including multiple versions of the
6e61fb
         same package) in the Maven repo.
6e61fb
     choices: [true, false]
6e61fb
     default: false
6e61fb
   extra:
6e61fb
     description:
6e61fb
       - set any extra parameters on this tag.
6e61fb
requirements:
6e61fb
  - "python >= 2.7"
6e61fb
  - "koji"
6e61fb
'''
6e61fb
6e61fb
EXAMPLES = '''
6e61fb
- name: create a main koji tag and candidate tag
6e61fb
  hosts: localhost
6e61fb
  tasks:
6e61fb
    - name: Create a main product koji tag
6e61fb
      koji_tag:
6e61fb
        koji: kojidev
6e61fb
        name: ceph-3.1-rhel-7
6e61fb
        arches: x86_64
6e61fb
        state: present
6e61fb
        packages:
6e61fb
          kdreyer:
6e61fb
            - ansible
6e61fb
            - ceph
6e61fb
            - ceph-ansible
6e61fb
6e61fb
    - name: Create a candidate koji tag
6e61fb
      koji_tag:
6e61fb
        koji: kojidev
6e61fb
        name: ceph-3.1-rhel-7-candidate
6e61fb
        state: present
6e61fb
        inheritance:
6e61fb
        - parent: ceph-3.1-rhel-7
6e61fb
          priority: 0
6e61fb
6e61fb
    - name: Create a tag that uses an external repo
6e61fb
      koji_tag:
6e61fb
        koji: kojidev
6e61fb
        name: storage7-ceph-nautilus-el7-build
6e61fb
        state: present
6e61fb
        external_repos:
6e61fb
        - repo: centos7-cr
6e61fb
          priority: 5
6e61fb
6e61fb
    - name: Create a tag that uses comps groups
6e61fb
      koji_tag:
6e61fb
        name: foo-el7-build
6e61fb
        groups:
6e61fb
          srpm-build:
6e61fb
            - rpm-build
6e61fb
            - fedpkg
6e61fb
'''
6e61fb
6e61fb
RETURN = ''' # '''
6e61fb
6e61fb
6e61fb
class DuplicateNameError(Exception):
6e61fb
    """ The user specified two external repos with the same name. """
6e61fb
    pass
6e61fb
6e61fb
6e61fb
class DuplicatePriorityError(Exception):
6e61fb
    """ The user specified two external repos with the same priority. """
6e61fb
    pass
6e61fb
6e61fb
6e61fb
def validate_repos(repos):
6e61fb
    """Ensure that each external repository has unique name and priority
6e61fb
    values.
6e61fb
6e61fb
    This prevents the user from accidentally specifying two or more external
6e61fb
    repositories with the same name or priority.
6e61fb
6e61fb
    :param repos: list of repository dicts
6e61fb
    :raises: DuplicatePriorityError if two repos have the same priority.
6e61fb
    """
6e61fb
    names = set()
6e61fb
    priorities = set()
6e61fb
    for repo in repos:
6e61fb
        name = repo['repo']
6e61fb
        priority = repo['priority']
6e61fb
        if name in names:
6e61fb
            raise DuplicateNameError(name)
6e61fb
        if priority in priorities:
6e61fb
            raise DuplicatePriorityError(priority)
6e61fb
        names.add(name)
6e61fb
        priorities.add(priority)
6e61fb
6e61fb
6e61fb
def normalize_inheritance(inheritance):
6e61fb
    """
6e61fb
    Transform inheritance module argument input into the format returned by
6e61fb
    getInheritanceData(). Only includes supported fields (excluding child_id
6e61fb
    and parent_id), renames "parent" to "name", chooses correct defaults for
6e61fb
    missing fields, and performs some limited type correction for maxdepth and
6e61fb
    priority.
6e61fb
6e61fb
    :param inheritance: list of inheritance dicts
6e61fb
    """
6e61fb
    normalized_inheritance = []
6e61fb
6e61fb
    for rule in inheritance:
6e61fb
        # maxdepth: treat empty strings the same as None
6e61fb
        maxdepth = rule.get('maxdepth')
6e61fb
        if maxdepth == '':
6e61fb
            maxdepth = None
6e61fb
        if isinstance(maxdepth, string_types):
6e61fb
            maxdepth = int(maxdepth)
6e61fb
6e61fb
        normalized_inheritance.append(dict(
6e61fb
            # we don't know child_id yet
6e61fb
            intransitive=rule.get('intransitive', False),
6e61fb
            maxdepth=maxdepth,
6e61fb
            name=rule['parent'],
6e61fb
            noconfig=rule.get('noconfig', False),
6e61fb
            # we don't know parent_id yet
6e61fb
            pkg_filter=rule.get('pkg_filter', ''),
6e61fb
            priority=int(rule['priority']),
6e61fb
        ))
6e61fb
6e61fb
    return sorted(normalized_inheritance, key=lambda i: i['priority'])
6e61fb
6e61fb
6e61fb
def ensure_inheritance(session, tag_name, tag_id, check_mode, inheritance):
6e61fb
    """
6e61fb
    Ensure that these inheritance rules are configured on this Koji tag.
6e61fb
6e61fb
    :param session: Koji client session
6e61fb
    :param str tag_name: Koji tag name
6e61fb
    :param int tag_id: Koji tag ID
6e61fb
    :param bool check_mode: don't make any changes
6e61fb
    :param list inheritance: ensure these rules are set, and no others
6e61fb
    """
6e61fb
    result = {'changed': False, 'stdout_lines': []}
6e61fb
6e61fb
    # resolve parent tag IDs
6e61fb
    rules = []
6e61fb
    for rule in normalize_inheritance(inheritance):
6e61fb
        parent_name = rule['name']
6e61fb
        parent_taginfo = session.getTag(parent_name)
6e61fb
        if not parent_taginfo:
6e61fb
            msg = "parent tag '%s' not found" % parent_name
6e61fb
            if check_mode:
6e61fb
                result['stdout_lines'].append(msg)
6e61fb
                # spoof to allow continuation
6e61fb
                parent_taginfo = {'id': 0}
6e61fb
            else:
6e61fb
                raise ValueError(msg)
6e61fb
        parent_id = parent_taginfo['id']
6e61fb
        rules.append(dict(rule, child_id=tag_id, parent_id=parent_id))
6e61fb
6e61fb
    current_inheritance = session.getInheritanceData(tag_name)
6e61fb
    if current_inheritance != rules:
6e61fb
        result['stdout_lines'].extend(
6e61fb
                ('current inheritance:',)
6e61fb
                + common_koji.describe_inheritance(current_inheritance)
6e61fb
                + ('new inheritance:',)
6e61fb
                + common_koji.describe_inheritance(rules))
6e61fb
        result['changed'] = True
6e61fb
        if not check_mode:
6e61fb
            common_koji.ensure_logged_in(session)
6e61fb
            session.setInheritanceData(tag_name, rules, clear=True)
6e61fb
    return result
6e61fb
6e61fb
6e61fb
def ensure_external_repos(session, tag_name, check_mode, repos):
6e61fb
    """
6e61fb
    Ensure that these external repos are configured on this Koji tag.
6e61fb
6e61fb
    :param session: Koji client session
6e61fb
    :param str tag_name: Koji tag name
6e61fb
    :param bool check_mode: don't make any changes
6e61fb
    :param list repos: ensure these external repos are set, and no others.
6e61fb
    """
6e61fb
    result = {'changed': False, 'stdout_lines': []}
6e61fb
    validate_repos(repos)
6e61fb
    current_repo_list = session.getTagExternalRepos(tag_name)
6e61fb
    current = {repo['external_repo_name']: repo for repo in current_repo_list}
6e61fb
    current_priorities = {
6e61fb
        str(repo['priority']): repo for repo in current_repo_list
6e61fb
    }
6e61fb
    for repo in sorted(repos, key=lambda r: r['priority']):
6e61fb
        repo_name = repo['repo']
6e61fb
        repo_priority = repo['priority']
6e61fb
        if repo_name in current:
6e61fb
            # The repo is present for this tag.
6e61fb
            # Now ensure the priority is correct.
6e61fb
            if repo_priority == current[repo_name]['priority']:
6e61fb
                continue
6e61fb
            result['changed'] = True
6e61fb
            msg = 'set %s repo priority to %i' % (repo_name, repo_priority)
6e61fb
            result['stdout_lines'].append(msg)
6e61fb
            if not check_mode:
6e61fb
                common_koji.ensure_logged_in(session)
6e61fb
                session.editTagExternalRepo(tag_name, repo_name, repo_priority)
6e61fb
            continue
6e61fb
        elif str(repo_priority) in current_priorities:
6e61fb
            # No need to check for name equivalence here; it would already
6e61fb
            # have happened
6e61fb
            result['changed'] = True
6e61fb
            msg = 'set repo at priority %i to %s' % (repo_priority, repo_name)
6e61fb
            result['stdout_lines'].append(msg)
6e61fb
            if not check_mode:
6e61fb
                common_koji.ensure_logged_in(session)
6e61fb
                same_priority_repo = current_priorities.get(
6e61fb
                        str(repo_priority)).get('external_repo_name')
6e61fb
                session.removeExternalRepoFromTag(tag_name, same_priority_repo)
6e61fb
                session.addExternalRepoToTag(
6e61fb
                        tag_name, repo_name, repo_priority)
6e61fb
                # Prevent duplicate attempts
6e61fb
                del current_priorities[str(repo_priority)]
6e61fb
            continue
6e61fb
        result['changed'] = True
6e61fb
        msg = 'add %s external repo to %s' % (repo_name, tag_name)
6e61fb
        result['stdout_lines'].append(msg)
6e61fb
        if not check_mode:
6e61fb
            common_koji.ensure_logged_in(session)
6e61fb
            session.addExternalRepoToTag(tag_name, repo_name, repo_priority)
6e61fb
    # Find the repos to remove from this tag.
6e61fb
    repo_names = [repo['repo'] for repo in repos]
6e61fb
    current_names = current.keys()
6e61fb
    repos_to_remove = set(current_names) - set(repo_names)
6e61fb
    for repo_name in repos_to_remove:
6e61fb
        result['changed'] = True
6e61fb
        msg = 'removed %s repo from %s tag' % (repo_name, tag_name)
6e61fb
        result['stdout_lines'].append(msg)
6e61fb
        if not check_mode:
6e61fb
            common_koji.ensure_logged_in(session)
6e61fb
            session.removeExternalRepoFromTag(tag_name, repo_name)
6e61fb
    return result
6e61fb
6e61fb
6e61fb
def ensure_packages(session, tag_name, tag_id, check_mode, packages):
6e61fb
    """
6e61fb
    Ensure that these packages are configured on this Koji tag.
6e61fb
6e61fb
    :param session: Koji client session
6e61fb
    :param str tag_name: Koji tag name
6e61fb
    :param int tag_id: Koji tag ID
6e61fb
    :param bool check_mode: don't make any changes
6e61fb
    :param dict packages: ensure these packages are set (?)
6e61fb
    """
6e61fb
    result = {'changed': False, 'stdout_lines': []}
6e61fb
    # Note: this in particular could really benefit from koji's
6e61fb
    # multicalls...
6e61fb
    common_koji.ensure_logged_in(session)
6e61fb
    current_pkgs = session.listPackages(tagID=tag_id)
6e61fb
    current_names = set([pkg['package_name'] for pkg in current_pkgs])
6e61fb
    # Create a "current_owned" dict to compare with what's in Ansible.
6e61fb
    current_owned = defaultdict(set)
6e61fb
    for pkg in current_pkgs:
6e61fb
        owner = pkg['owner_name']
6e61fb
        pkg_name = pkg['package_name']
6e61fb
        current_owned[owner].add(pkg_name)
6e61fb
    for owner, owned in packages.items():
6e61fb
        for package in owned:
6e61fb
            if package not in current_names:
6e61fb
                # The package was missing from the tag entirely.
6e61fb
                if not check_mode:
6e61fb
                    session.packageListAdd(tag_name, package, owner)
6e61fb
                result['stdout_lines'].append('added pkg %s' % package)
6e61fb
                result['changed'] = True
6e61fb
            else:
6e61fb
                # The package is already in this tag.
6e61fb
                # Verify ownership.
6e61fb
                if package not in current_owned.get(owner, []):
6e61fb
                    if not check_mode:
6e61fb
                        session.packageListSetOwner(tag_name, package, owner)
6e61fb
                    result['stdout_lines'].append('set %s owner %s' %
6e61fb
                                                  (package, owner))
6e61fb
                    result['changed'] = True
6e61fb
    # Delete any packages not in Ansible.
6e61fb
    all_names = [name for names in packages.values() for name in names]
6e61fb
    delete_names = set(current_names) - set(all_names)
6e61fb
    for package in delete_names:
6e61fb
        result['stdout_lines'].append('remove pkg %s' % package)
6e61fb
        result['changed'] = True
6e61fb
        if not check_mode:
6e61fb
            session.packageListRemove(tag_name, package, owner)
6e61fb
    return result
6e61fb
6e61fb
6e61fb
def ensure_groups(session, tag_id, check_mode, desired_groups):
6e61fb
    """
6e61fb
    Ensure that these groups are configured on this Koji tag.
6e61fb
6e61fb
    :param session: Koji client session
6e61fb
    :param int tag_id: Koji tag ID
6e61fb
    :param bool check_mode: don't make any changes
6e61fb
    :param dict desired_groups: ensure these groups are set (?)
6e61fb
    """
6e61fb
    result = {'changed': False, 'stdout_lines': []}
6e61fb
    common_koji.ensure_logged_in(session)
6e61fb
    current_groups = session.getTagGroups(tag_id)
6e61fb
    for group in current_groups:
6e61fb
        if group['tag_id'] == tag_id and group['name'] not in desired_groups:
6e61fb
            if not check_mode:
6e61fb
                session.groupListRemove(tag_id, group['name'])
6e61fb
            result['stdout_lines'].append('removed group %s' % group['name'])
6e61fb
            result['changed'] = True
6e61fb
    for group_name, desired_pkgs in desired_groups.items():
6e61fb
        for group in current_groups:
6e61fb
            if group['name'] == group_name:
6e61fb
                current_pkgs = {entry['package']: entry['tag_id']
6e61fb
                                for entry in group['packagelist']}
6e61fb
                break
6e61fb
        else:
6e61fb
            current_pkgs = {}
6e61fb
            if not check_mode:
6e61fb
                session.groupListAdd(tag_id, group_name)
6e61fb
            result['stdout_lines'].append('added group %s' % group_name)
6e61fb
            result['changed'] = True
6e61fb
6e61fb
        for package, pkg_tag_id in current_pkgs.items():
6e61fb
            if pkg_tag_id == tag_id and package not in desired_pkgs:
6e61fb
                if not check_mode:
6e61fb
                    session.groupPackageListRemove(tag_id, group_name, package)
6e61fb
                result['stdout_lines'].append('removed pkg %s from group %s' % (package, group_name))
6e61fb
                result['changed'] = True
6e61fb
        for package in desired_pkgs:
6e61fb
            if package not in current_pkgs:
6e61fb
                if not check_mode:
6e61fb
                    session.groupPackageListAdd(tag_id, group_name, package)
6e61fb
                result['stdout_lines'].append('added pkg %s to group %s' % (package, group_name))
6e61fb
                result['changed'] = True
6e61fb
    return result
6e61fb
6e61fb
6e61fb
def compound_parameter_present(param_name, param, expected_type):
6e61fb
    if param not in (None, ''):
6e61fb
        if not isinstance(param, expected_type):
6e61fb
            raise ValueError(param_name + ' must be a '
6e61fb
                             + expected_type.__class__.__name__
6e61fb
                             + ', not a ' + param.__class__.__name__)
6e61fb
        return True
6e61fb
    return False
6e61fb
6e61fb
6e61fb
def ensure_tag(session, name, check_mode, inheritance, external_repos,
6e61fb
               packages, groups, **kwargs):
6e61fb
    """
6e61fb
    Ensure that this tag exists in Koji.
6e61fb
6e61fb
    :param session: Koji client session
6e61fb
    :param name: Koji tag name
6e61fb
    :param check_mode: don't make any changes
6e61fb
    :param inheritance: Koji tag inheritance settings. These will be translated
6e61fb
                        for Koji's setInheritanceData RPC.
6e61fb
    :param external_repos: Koji external repos to set for this tag.
6e61fb
    :param packages: dict of packages to add ("whitelist") for this tag.
6e61fb
                     If this is an empty dict, we don't touch the package list
6e61fb
                     for this tag.
6e61fb
    :param groups: dict of comps groups to set for this tag.
6e61fb
    :param **kwargs: Pass remaining kwargs directly into Koji's createTag and
6e61fb
                     editTag2 RPCs.
6e61fb
    """
6e61fb
    taginfo = session.getTag(name)
6e61fb
    result = {'changed': False, 'stdout_lines': []}
6e61fb
    if not taginfo:
6e61fb
        if check_mode:
6e61fb
            result['stdout_lines'].append('would create tag %s' % name)
6e61fb
            result['changed'] = True
6e61fb
            return result
6e61fb
        common_koji.ensure_logged_in(session)
6e61fb
        if 'perm' in kwargs and kwargs['perm']:
6e61fb
            kwargs['perm'] = common_koji.get_perm_id(session, kwargs['perm'])
6e61fb
        id_ = session.createTag(name, parent=None, **kwargs)
6e61fb
        result['stdout_lines'].append('created tag id %d' % id_)
6e61fb
        result['changed'] = True
6e61fb
        taginfo = {'id': id_}  # populate for inheritance management below
6e61fb
    else:
6e61fb
        # The tag name already exists. Ensure all the parameters are set.
6e61fb
        edits = {}
6e61fb
        edit_log = []
6e61fb
        for key, value in kwargs.items():
6e61fb
            if taginfo[key] != value and value is not None:
6e61fb
                edits[key] = value
6e61fb
                edit_log.append('%s: changed %s from "%s" to "%s"'
6e61fb
                                % (name, key, taginfo[key], value))
6e61fb
        # Find out which "extra" items we must explicitly remove
6e61fb
        # ("remove_extra" argument to editTag2).
6e61fb
        if 'extra' in kwargs and kwargs['extra'] is not None:
6e61fb
            for key in taginfo['extra']:
6e61fb
                if key not in kwargs['extra']:
6e61fb
                    if 'remove_extra' not in edits:
6e61fb
                        edits['remove_extra'] = []
6e61fb
                    edits['remove_extra'].append(key)
6e61fb
            if 'remove_extra' in edits:
6e61fb
                edit_log.append('%s: remove extra fields "%s"'
6e61fb
                                % (name, '", "'.join(edits['remove_extra'])))
6e61fb
        if edits:
6e61fb
            result['stdout_lines'].extend(edit_log)
6e61fb
            result['changed'] = True
6e61fb
            if not check_mode:
6e61fb
                common_koji.ensure_logged_in(session)
6e61fb
                session.editTag2(name, **edits)
6e61fb
6e61fb
    # Ensure inheritance rules are all set.
6e61fb
    if compound_parameter_present('inheritance', inheritance, list):
6e61fb
        inheritance_result = ensure_inheritance(session, name, taginfo['id'],
6e61fb
                                                check_mode, inheritance)
6e61fb
        if inheritance_result['changed']:
6e61fb
            result['changed'] = True
6e61fb
        result['stdout_lines'].extend(inheritance_result['stdout_lines'])
6e61fb
6e61fb
    # Ensure external repos.
6e61fb
    if compound_parameter_present('external_repos', external_repos, list):
6e61fb
        repos_result = ensure_external_repos(session, name, check_mode,
6e61fb
                                             external_repos)
6e61fb
        if repos_result['changed']:
6e61fb
            result['changed'] = True
6e61fb
        result['stdout_lines'].extend(repos_result['stdout_lines'])
6e61fb
6e61fb
    # Ensure package list.
6e61fb
    if compound_parameter_present('packages', packages, dict):
6e61fb
        packages_result = ensure_packages(session, name, taginfo['id'],
6e61fb
                                          check_mode, packages)
6e61fb
        if packages_result['changed']:
6e61fb
            result['changed'] = True
6e61fb
        result['stdout_lines'].extend(packages_result['stdout_lines'])
6e61fb
6e61fb
    # Ensure group list.
6e61fb
    if compound_parameter_present('groups', groups, dict):
6e61fb
        groups_result = ensure_groups(session, taginfo['id'],
6e61fb
                                      check_mode, groups)
6e61fb
        if groups_result['changed']:
6e61fb
            result['changed'] = True
6e61fb
        result['stdout_lines'].extend(groups_result['stdout_lines'])
6e61fb
6e61fb
    return result
6e61fb
6e61fb
6e61fb
def delete_tag(session, name, check_mode):
6e61fb
    """ Ensure that this tag is deleted from Koji. """
6e61fb
    taginfo = session.getTag(name)
6e61fb
    result = dict(
6e61fb
        stdout='',
6e61fb
        changed=False,
6e61fb
    )
6e61fb
    if taginfo:
6e61fb
        result['stdout'] = 'deleted tag %d' % taginfo['id']
6e61fb
        result['changed'] = True
6e61fb
        if not check_mode:
6e61fb
            common_koji.ensure_logged_in(session)
6e61fb
            session.deleteTag(name)
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
        state=dict(type='str', choices=[
6e61fb
                   'present', 'absent'], required=False, default='present'),
6e61fb
        inheritance=dict(type='raw', required=False, default=None),
6e61fb
        external_repos=dict(type='raw', required=False, default=None),
6e61fb
        packages=dict(type='raw', required=False, default=None),
6e61fb
        groups=dict(type='raw', required=False, default=None),
6e61fb
        arches=dict(type='str', required=False, default=None),
6e61fb
        perm=dict(type='str', required=False, default=None),
6e61fb
        locked=dict(type='bool', required=False, default=False),
6e61fb
        maven_support=dict(type='bool', required=False, default=False),
6e61fb
        maven_include_all=dict(type='bool', required=False, default=False),
6e61fb
        extra=dict(type='dict', required=False, default=None),
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
    state = params['state']
6e61fb
6e61fb
    session = common_koji.get_session(profile)
6e61fb
6e61fb
    if state == 'present':
6e61fb
        result = ensure_tag(session, name,
6e61fb
                            check_mode,
6e61fb
                            inheritance=params['inheritance'],
6e61fb
                            external_repos=params['external_repos'],
6e61fb
                            packages=params['packages'],
6e61fb
                            groups=params['groups'],
6e61fb
                            arches=params['arches'],
6e61fb
                            perm=params['perm'] or None,
6e61fb
                            locked=params['locked'],
6e61fb
                            maven_support=params['maven_support'],
6e61fb
                            maven_include_all=params['maven_include_all'],
6e61fb
                            extra=params['extra'])
6e61fb
    elif state == 'absent':
6e61fb
        result = delete_tag(session, name, check_mode)
6e61fb
6e61fb
    module.exit_json(**result)
6e61fb
6e61fb
6e61fb
def main():
6e61fb
    run_module()
6e61fb
6e61fb
6e61fb
if __name__ == '__main__':
6e61fb
    main()