Python 脚本无法调用 Jira REST API

Python script fails to call Jira REST API

我有一个 python 脚本,它调用 Jira API 来创建 Jira 问题。 API Call 本身工作正常,如果我用 Postman 测试它,我可以创建票证但是同样的 URL 不能使用 Python.I 不明白为什么我不能创建与 jira

的安全连接
Executed [createIssue] action via OEC[integrationId: f457bfd9-5fe0-4fc5-89a9-ee007e85cf1b integrationType: Jira] with errors. Reason: Err: exit status 1, Stderr: Traceback (most recent call last): File 
"/home/opsgenie/oec_test/scripts/actionExecutor.py", line 279, in <module> main() File "/home/opsgenie/oec_test/scripts/actionExecutor.py", line 233, in main timeout=timeout) File 
"/usr/lib/python2.7/dist-packages/requests/api.py", line 112, in post return request('post', url, data=data, json=json, **kwargs) File "/usr/lib/python2.7/dist-packages/requests/api.py", line 58, in request return session.request(method=method, url=url, **kwargs) File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 520, in 
request resp = self.send(prep, **send_kwargs) File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 630, in send r = adapter.send(request, **kwargs) File 
"/usr/lib/python2.7/dist-packages/requests/adapters.py", line 508, in send raise 
ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPSConnectionPool(host='jiratest.gk.gk-software.com', port=443): Max retries exceeded with url: /rest/api/2/issue 
(Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7ffa264aa1d0>: Failed to establish a new connection: [Errno -2] Name or service not known',))

完整的代码如下所示:

import argparse
import json
import logging
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import re

import requests
from requests.auth import HTTPBasicAuth

parser = argparse.ArgumentParser()
parser.add_argument('-payload', '--queuePayload', help='Payload from queue', required=True)
parser.add_argument('-apiKey', '--apiKey', help='The apiKey of the integration', required=True)
parser.add_argument('-opsgenieUrl', '--opsgenieUrl', help='The url', required=True)
parser.add_argument('-logLevel', '--logLevel', help='Level of log', required=True)
parser.add_argument('-username', '--username', help='Username', required=False)
parser.add_argument('-password', '--password', help='Password', required=False)
parser.add_argument('-url', '--url', help='URL', required=False)
parser.add_argument('-projectKey', '--projectKey', help='Project Key', required=False)
parser.add_argument('-issueTypeName', '--issueTypeName', help='Issue Type', required=False)
args = vars(parser.parse_args())

logging.basicConfig(stream=sys.stdout, level=args['logLevel'])


def parse_field(key, mandatory):
    variable = queue_message.get(key)
    if not variable:
        variable = args.get(key)
    if mandatory and not variable:
        logging.error(LOG_PREFIX + " Skipping action, Mandatory conf item '" + key +
                      "' is missing. Check your configuration file.")
        raise ValueError(LOG_PREFIX + " Skipping action, Mandatory conf item '" + key +
                         "' is missing. Check your configuration file.")
    return variable


def parse_timeout():
    parsed_timeout = args.get('http.timeout')
    if not parsed_timeout:
        return 30000
    return int(parsed_timeout)
    
def get_alert_details(alertId):
        alert_api_url = args['opsgenieUrl'] + "/v2/alerts/" + alertId
        headers = {
            "Content-Type": "application/json",
            "Accept-Language": "application/json",
            "Authorization": "GenieKey " + args['apiKey']
        }
        req = requests.get(alert_api_url, headers=headers)
        alert = req.json()

        return alert["data"]
    
def get_transition_id(request_headers, jira_url, transition_name, token):
    transition_id = str()
    response = requests.get(jira_url, None, headers=request_headers, auth=token, timeout=timeout)
    try:
        body = response.json()
        if body and response.status_code < 299:
            transition_list = body["transitions"]
            for transition in transition_list:
                to = transition['to']
                if transition_name == to['name']:
                    transition_id = transition['id']
            logging.info(LOG_PREFIX + " Successfully executed at Jira")
            logging.debug(LOG_PREFIX + " Jira response: " + str(response.status_code) + " " + str(response.content))
        else:
            logging.error(
                LOG_PREFIX + " Could not execute at Jira; response: " + str(response.content) + " status code: " + str(
                    response.status_code))
        if not transition_id:
            logging.debug(LOG_PREFIX + " Transition id is empty")
        return transition_id
    except ValueError:
        logging.error("The response body is not a valid json object!")
        
def get_comp():
    
    jira_comp = re.search(r"topic:\s\'(.*)[']", str(queue_message.get("description")))
    if jira_comp:
        jira_comp = jira_comp.group(1)
        return (jira_comp)
    else:
        jira_comp = "Dummy"
        return (jira_comp)
    

def get_prio():
    
    severity = re.search(r"severity:\s\'(.*)[']",queue_message.get("description"))
    if severity:
        jira_prio = severity.group(1)
        if jira_prio == "critical":
            jira_prio = "Very High"
            return (jira_prio)
        if jira_prio == "Very High":
            jira_prio = "High"
            return (jira_prio)
    else:
        severity = "High"
        return (severity)
    
    
def get_context():
    
    context = re.search(r"context:\s\'(.*)[']", str(queue_message.get("description")))    
    if context:
        context = context.group(1)
        return (context)
    else:
        context = ""
        return (context)
    

def main():
    global LOG_PREFIX
    global queue_message
    global timeout
    global to_customfield_20500; to_customfield_20500=[] 
    global project_to_customfield_20500
    global cluster_to_customfield_20500
    
    queue_message_string = args['queuePayload']
    queue_message_string = queue_message_string.strip()
    queue_message = json.loads(queue_message_string)

   
    alert_id = queue_message["alertId"]
    mapped_action = queue_message["mappedActionV2"]["name"]
    alert_details = get_alert_details(alert_id)
    LOG_PREFIX = "[" + mapped_action + "]"

    logging.info("Will execute " + mapped_action + " for alertId " + alert_id)

    timeout = parse_timeout()
    url = parse_field('url', True)
    username = parse_field('username', True)
    password = parse_field('password', True)
    project_key = parse_field('projectKey', False)
    issue_type_name = parse_field('issueTypeName', False)

    issue_key = queue_message.get("key")

    logging.debug("Url: " + str(url))
    logging.debug("Username: " + str(username))
    logging.debug("Project Key: " + str(project_key))
    logging.debug("Issue Type: " + str(issue_type_name))
    logging.debug("Issue Key: " + str(issue_key))

    content_params = dict()

    token = HTTPBasicAuth(username, password)
    headers = {
        "Content-Type": "application/json",
        "Accept-Language": "application/json",
    }

    result_url = url + "/rest/api/2/issue"
    
    if mapped_action == "addCommentToIssue":
        content_params = {
            "body": queue_message.get('body')
        }
        result_url += "/" + issue_key + "/comment"
    elif mapped_action == "createIssue":
  
        getcontext = get_context()
        getcomp = get_comp()
        priority = get_prio()


        content_params = {
            "fields": {
                "project": {"key": project_key},
                "issuetype": {"name": issue_type_name},
                "summary": queue_message.get("summary"),
                "description": queue_message.get("description"),              
                "customfield_20500": [{"value": "DE - Germany"}],
                "customfield_13604": "tbd",
                "components": [{"name": getcomp}],
                "versions": [{"name": "tbd"}],
                "customfield_15000": [getcontext],
                "priority": {"name": priority},
                "assignee": {"name": "#cloudoperations"}
            }
        }
    elif mapped_action == "resolveIssue":
        result_url += "/" + issue_key + "/transitions"
        content_params = {
            "transition": {
                "id": get_transition_id(headers, result_url, "Resolved", token)
            },
            "fields": {
                "resolution": {
                    "name": "Done"
                }
            }
        }
    elif mapped_action == "closeIssue":
        result_url += "/" + issue_key + "/transitions"
        content_params = {
            "transition": {
                "id": get_transition_id(headers, result_url, "Closed", token)
            },
            "fields": {
                "resolution": {
                    "name": "Done"
                }
            }
        }
    elif mapped_action == "issueDone":
        result_url += "/" + issue_key + "/transitions"
        content_params = {
            "transition": {
                "id": get_transition_id(headers, result_url, "Done", token)
            }
        }
    elif mapped_action == "inProgressIssue":
        result_url += "/" + issue_key + "/transitions"
        content_params = {
            "transition": {
                "id": get_transition_id(headers, result_url, "In Progress", token)
            }
        }

    logging.debug(str(content_params))
    response = requests.post(result_url, data=json.dumps(content_params), headers=headers, auth=token,
                             timeout=timeout)
    if response.status_code < 299:
        logging.info("Successfully executed at Jira")
        if mapped_action == "createIssue":
            try:
                response_body = response.json()
                if response_body:
                    issue_key_from_response = response_body['key']
                    if issue_key_from_response:
                        alert_api_url = args['opsgenieUrl'] + "/v2/alerts/" + alert_id + "/details"
                        content = {
                            "details":
                                {
                                    "issueKey": issue_key_from_response
                                }
                        }
                        headers = {
                            "Content-Type": "application/json",
                            "Accept-Language": "application/json",
                            "Authorization": "GenieKey " + args['apiKey']
                        }
                        logging.debug(str(alert_api_url) + str(content) + str(headers))
                        alert_response = requests.post(alert_api_url,
                                                       data=json.dumps(content), headers=headers,
                                                       timeout=timeout)
                        if alert_response.status_code < 299:
                            logging.info(LOG_PREFIX + " Successfully sent to Opsgenie")
                            logging.debug(
                                LOG_PREFIX + " Jira response: " + str(alert_response.content) + " " + str(
                                    alert_response.status_code))
                        else:
                            logging.warning(
                                LOG_PREFIX + " Could not execute at Opsgenie; response: " + str(
                                    alert_response.content) + " status code: " + str(alert_response.status_code))
                else:
                    logging.warning(
                        LOG_PREFIX + " Jira response is empty")
            except ValueError:
                logging.error(ValueError)
    else:
        logging.warning(
            LOG_PREFIX + " Could not execute at Jira; response: " + str(response.content) + " status code: " + str(
                response.status_code))


if __name__ == '__main__':
    main()

我也不确定,但我建议使用 Jira Python 库,后者又使用请求库

我发现这是执行 py 脚本的 VM 的连接问题,无法访问 jira URL