#!/usr/bin/python RETURN = '''# ''' import datetime try: import gitlab HAS_GITLAB_PACKAGE = True except: HAS_GITLAB_PACKAGE = False class GitLabProject(object): namespace = '' nid = False pid = False is_user = False project = None def __init__(self, module, git): self._module = module self._gitlab = git def exists(self, group_name, project_name): if not self.findNamespace(group_name): return False project = self._gitlab.projects.get('%s/%s' % (self.namespace, project_name)) if project: namespace = project.namespace if namespace.id == self.nid: if (not self.is_user and not hasattr(namespace, 'owner_id')) or (self.is_user and hasattr(namespace, 'owner_id')): if project.name.lower() == project_name or project.path.lower() == project_name: self.pid = project.id self.project = project return True return False def findNamespace(self, group_name): if self.nid: return True if group_name is not None: # Find the group, if group not exists we try for user group_name = unicode(group_name) for group in self._gitlab.namespaces.list(search=group_name): if group.path.lower() == group_name: self.namespace = group_name self.nid = group.id return True user_name = group_name else: user_name = self._gitlab.user.username user_data = self._gitlab.users.list(username=user_name) for user in user_data: if hasattr(user, 'id'): self.namespace = user_name self.nid = user.id self.is_user = True return True return False def findIssues(self, title): return self.project.issues.list(state='opened') class GitLabMilestone(object): mid = False def __init__(self, module, git): self._module = module self._gitlab = git def exists(self, project_id, milestone_name): if self.mid: return True if milestone_name is not None: milestone_name = unicode(milestone_name) found_milestones = self._gitlab.project_milestones.list(project_id=project_id) for milestone in found_milestones: if milestone.title.lower() == milestone_name: self.mid = milestone.id return True return False class GitLabUser(object): uid = False def __init__(self, module, git): self._module = module self._gitlab = git def exists(self, username): if self.uid: return True if username is not None: username = unicode(username) found_user = self._gitlab.users.list(username=username) for user in found_user: if user.name.lower() == username or user.username.lower() == username: self.uid = user.id return True return False def main(): module = AnsibleModule( argument_spec=dict( server_url=dict(required=True), validate_certs=dict(required=False, default=True, type='bool', aliases=['verify_ssl']), login_user=dict(required=False, no_log=True), login_password=dict(required=False, no_log=True), login_token=dict(required=False, no_log=True), group=dict(required=False), name=dict(required=True), title=dict(required=True), append_timestamp=dict(required=False, default=False, type='bool'), description=dict(required=False), confidential=dict(required=False, default=False, type='bool'), assignee=dict(required=False), milestone=dict(required=False), labels=dict(required=False, type='list'), update=dict(required=False, default=False, type='bool'), close=dict(required=False, default=False, type='bool'), ), supports_check_mode=True ) if not HAS_GITLAB_PACKAGE: module.fail_json(msg="Missing required gitlab module (check docs or install with: pip install python-gitlab") server_url = module.params['server_url'] verify_ssl = module.params['validate_certs'] login_user = module.params['login_user'] login_password = module.params['login_password'] login_token = module.params['login_token'] group_name = module.params['group'] project_name = module.params['name'] title = module.params['title'] append_timestamp = module.params['append_timestamp'] description = module.params['description'] confidential = module.params['confidential'] assignee = module.params['assignee'] milestone_name = module.params['milestone'] labels = module.params['labels'] update = module.params['update'] close = module.params['close'] # We need both login_user and login_password or login_token, otherwise we fail. if login_user is not None and login_password is not None: use_credentials = True elif login_token is not None: use_credentials = False else: module.fail_json(msg="No login credentials are given. Use login_user with login_password, or login_token") return # Gitlab API makes no difference between upper and lower cases, so we lower them. project_name = project_name.lower() if group_name is not None: group_name = group_name.lower() # Lets make an connection to the Gitlab server_url, with either login_user and login_password # or with login_token try: if use_credentials: git = gitlab.Gitlab(server_url, email=login_user, password=login_password, ssl_verify=verify_ssl) else: git = gitlab.Gitlab(server_url, login_token, ssl_verify=verify_ssl) git.auth() except Exception, e: module.fail_json(msg="Failed to connect to Gitlab server: %s " % e) return # Validate if project exists and get its ID project = GitLabProject(module, git) project_exists = project.exists(group_name, project_name) if not project_exists: module.fail_json(msg="Gitlab project does not exist") # Validate if user exists and get its ID user = GitLabUser(module, git) user_exists = user.exists(assignee) assignee_id = None if user_exists: assignee_id = user.uid # Validate if milestone exists and get its ID milestone = GitLabMilestone(module, git) milestone_exists = milestone.exists(project.pid, milestone_name) milestone_id = None if milestone_exists: milestone_id = milestone.mid if labels is None: labels = [] if update: issues = project.findIssues(title) updated = 0 if issues: for issue in issues: if issue.title.find(title) == 0: updated += 1 if description: git.project_issue_notes.create({'body': description}, project_id=project.pid, issue_id=issue.id) if assignee_id: issue.assignee_id = assignee_id if milestone_id: issue.milestone_id = milestone_id for label in labels: if label not in labels: issue.labels.append(label) if close: issue.state_event = 'close' issue.save() if updated > 0: module.exit_json(changed=True, result="Successfully updated %d issue(s) in project %s" % (updated, project_name)) # If we haven't found an issue to update, we're going to create a new one if append_timestamp: title = "%s (%s)" % (title, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) # Creating the issue dict arguments = {"title": title, "description": description, "confidential": confidential, "assignee_id": assignee_id, "milestone_id": milestone_id, "labels": ','.join(labels) } issue = git.project_issues.create(arguments, project_id=project.pid) if issue: if close: issue.state_event = 'close' issue.save() module.exit_json(changed=True, result="Successfully created issue %s in project %s" % (title, project_name)) else: module.fail_json(msg="Creating new issue failed", response=issue) from ansible.module_utils.basic import * if __name__ == '__main__': main()