0

我有一个 python 脚本,它调用 Jira API 来创建 Jira 问题。API 调用本身工作正常,如果我用 Postman 测试它,我可以创建票证,但是使用 Python 时相同的 URL 不起作用。我不明白为什么我无法创建与 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()
4

2 回答 2

0

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

于 2021-12-09T17:21:16.840 回答
0

我发现这是一个连接问题,因为从执行 py 脚本的 VM 开始,无法访问 jira URL

于 2021-12-13T08:25:04.607 回答