# -*- coding: utf-8 -*- # Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import jira from appenlight.models.integrations import IntegrationBase, IntegrationException _ = str class NotFoundException(Exception): pass class JiraIntegration(IntegrationBase): __mapper_args__ = {"polymorphic_identity": "jira"} front_visible = True as_alert_channel = False supports_report_alerting = False action_notification = True integration_action = "Add issue to Jira" class JiraClient(object): def __init__(self, user_name, password, host_name, project, request=None): self.user_name = user_name self.password = password self.host_name = host_name self.project = project self.request = request try: self.client = jira.client.JIRA( options={"server": host_name}, basic_auth=(user_name, password) ) except jira.JIRAError as e: raise IntegrationException( "Communication problem: HTTP_STATUS:%s, URL:%s " % (e.status_code, e.url) ) def get_projects(self): projects = self.client.projects() return projects def get_assignees(self, request): """Gets list of possible assignees""" cache_region = request.registry.cache_regions.redis_sec_30 @cache_region.cache_on_arguments("JiraClient.get_assignees") def cached(project_name): users = self.client.search_assignable_users_for_issues( None, project=project_name ) results = [] for user in users: results.append({"id": user.name, "name": user.displayName}) return results return cached(self.project) def get_issue_types(self, request): metadata = self.get_metadata(request) assignees = self.get_assignees(request) parsed_metadata = [] for entry in metadata["projects"][0]["issuetypes"]: issue = {"name": entry["name"], "id": entry["id"], "fields": []} for i_id, field_i in entry["fields"].items(): field = { "name": field_i["name"], "id": i_id, "required": field_i["required"], "values": [], "type": field_i["schema"].get("type"), } if field_i.get("allowedValues"): field["values"] = [] for i in field_i["allowedValues"]: field["values"].append( {"id": i["id"], "name": i.get("name", i.get("value", ""))} ) if field["id"] == "assignee": field["values"] = assignees issue["fields"].append(field) parsed_metadata.append(issue) return parsed_metadata def get_metadata(self, request): # cache_region = request.registry.cache_regions.redis_sec_30 # @cache_region.cache_on_arguments('JiraClient.get_metadata') def cached(project_name): return self.client.createmeta( projectKeys=project_name, expand="projects.issuetypes.fields" ) return cached(self.project) def create_issue(self, form_data, request): issue_types = self.get_issue_types(request) payload = { "project": {"key": form_data["project"]}, "summary": form_data["title"], "description": form_data["content"], "issuetype": {"id": form_data["issue_type"]}, "priority": {"id": form_data["priority"]}, "assignee": {"name": form_data["responsible"]}, } for issue_type in issue_types: if issue_type["id"] == form_data["issue_type"]: for field in issue_type["fields"]: # set some defaults for other required fields if field == "reporter": payload["reporter"] = {"id": self.user_name} if field["required"] and field["id"] not in payload: if field["type"] == "array": payload[field["id"]] = [field["values"][0]] elif field["type"] == "string": payload[field["id"]] = "" new_issue = self.client.create_issue(fields=payload) web_url = self.host_name + "/browse/" + new_issue.key to_return = { "id": new_issue.id, "resource_url": new_issue.self, "web_url": web_url, } return to_return