본문 바로가기

DevOps/JIRA & API Gateway

JIRA & API GW를 통해 Jenkins 배포 승인체계 구성하기 - 4. Lambda 세팅

먼저 라이브러리로 python request 라이브러리가 필요합니다.

 

특정 라이브러리만 다운받아서 Lambda Layer에 올려야하기 때문에 아래와 같이 수행해주세요.

python3 -m pip install --target "path" requests

 

혹은 아래 zip을 받아서 바로 Python3.7 Layer에 올리셔도 무방합니다.

 

Requests-Lib-a92ba28c-5cfe-465a-aa77-904b2c238082.zip
0.91MB

레이어 구성방법은 https://aws-diary.tistory.com/100?category=753099 글에서도 나와있으니 참고하시면 됩니다.

어렵지 않아서 사실 그냥 진행하셔도 무방할겁니다.

 

지라 이슈를 만드는 람다 소스코드는 아래와 같습니다.

{} 안에 있는 값들은 반드시 변경하여서 사용하시기 바랍니다.

description의 값을 event에서 받아서 던지시면,

지라 이슈 설명에 적고자 하는 원하는 내용을 작성하실 수 있습니다.

import json
import datetime
import requests
from requests.auth import HTTPBasicAuth

def lambda_handler(event, context):
    #SET URL
    jira_url = "{JIRA URL}"
    api_url = "/rest/api/2/issue"
    url = jira_url + api_url
    
    #SET AUTH
    auth = HTTPBasicAuth("{id}", "{pw}")
    
    #SET HEADER
    headers = {
       "Accept": "application/json",
       "Content-Type": "application/json"
    }
    
    #SET DUE DATE
    now = datetime.datetime.now()
    nowDate = now.strftime('%Y-%m-%d')

    #SET SUMMARY
    build_info = event['params']['header']['buildinfo'].split('/')
    print(build_info)
    build_name = build_info[0]
    build_num = build_info[1]
    summary = build_name + " " + build_num + " [배포 요청]"
    print(summary)
    
    #SET DESCRIPTION
    description = "Jira - Jenkins - AWS 연동"

    payload = json.dumps({
        "fields": {
            "project": {
                "key": "{Project Name}"
            },
            "summary": summary,
            "description": description,
            "customfield_10300": nowDate,
            "issuetype": {
                "name": "Task"
            },
            "assignee": {
                "name": "{지정하고 싶은 담당자}"
            }
        }
    })
    
    response = requests.request(
       "POST",
       url,
       data=payload,
       headers=headers,
       auth=auth
    )
    print(response.text)
    result = response.json()
    return result["id"]

 

다음은 JIRA Web Hook을 했을 때, 잠시 대기중인 Jenkins에 Rest API를 콜하는 람다입니다.

이 람다는 사실 Slack과 연동하는 부분과 거의 동일합니다. (따라서 젠킨스 API Key를 먼저 설정해 주셔야 합니다.)

 

Jenkins REST API를 사용하려면, 젠킨스 계정에서 API Key를 생성해야합니다.

유저 -> 사용하고자 하는 계정 -> 설정에서 Add new Token을 해주세요

 

그리고 해당 값을 람다 환경변수에 넣도록 하겠습니다.

 

 

아래 담당자 이름은 승인버튼을 클릭하는 담당자여야 합니다.

import os
import json
import requests
from requests.auth import HTTPBasicAuth

def get_issue_info(issue_id):
    #SET URL
    jira_url = "{JIRA URL}"
    api_url = "/rest/api/2/search?jql=issue=" + issue_id
    url = jira_url + api_url
    
    #SET AUTH
    auth = HTTPBasicAuth("{id}", "{pw}")
    
    #SET HEADER
    headers = {
       "Accept": "application/json",
       "Content-Type": "application/json"
    }
    
    response = requests.request(
       "GET",
       url,
       headers=headers,
       auth=auth
    )
    result = response.json()
    build_info = result["issues"][0]["fields"]["summary"].split(' ')
    return build_info

def call_jenkins_rest_api(status, build_info):
    #SET JENKINS AUTH
    UserName = "approver"
    PassWord = os.environ['jenkins_api_key']
    InputId = "80adb01b62fc2c9465c11b6c53a29857"
    
    #GET BUILD INFO
    build_name = build_info[0]
    build_num = build_info[1]
    
    #SET JENKINS HEADERS
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' 
    }
    
    #SET APPROVE CODE
    if status == "승인":
        approval = "YES"
    else:
        approval = "NO"
    form_data = "json=%7B%22parameter%22%3A%20%5B%7B%22name%22%3A%20%22APPROVE%22%2C%20%22value%22%3A%20%22"+approval+"%22%7D%5D%7D"
    
    #SET URL
    domain = '{JENKISN URL}'
    url = domain + '/job/'+build_name+'/'+build_num+'/wfapi/inputSubmit?inputId=' + InputId     
    
    #REQUEST
    response = requests.post(url, headers=headers, auth=HTTPBasicAuth(UserName, PassWord), data=form_data)
    print(response.text)
    if response.status_code == 200:
        if approval == "YES":
            return {
                "text": "Success Approve Build"
            }
        else:
            return {
                "text": "Abort This Build"
            }
    else:
        return {
            "text": "Failed Approve Build"
        }

def lambda_handler(event, context):
    print(event)
    approver = event['body-json']['user']['displayName']
    status = event['body-json']['issue']['fields']['status']['description']
    issue_id = event['params']['path']['issue']
    print(issue_id)
    
    if approver == "{JIRA 담당자 이름}":
        build_info = get_issue_info(issue_id)
        call_jenkins_rest_api(status, build_info)
        print(approver + "님이 " + status + "하셨습니다.")
    else:
        print("인가된 사용자가 아닙니다.")

 

마지막으로 배포가 끝났을 경우, 지라 이슈를 완료로 업데이트 하는 람다입니다.

transition_id 값을 반드시 이전에 지라 워크 플로우를 세팅할 때, 있었던 완료 값으로 해주셔야 합니다.

text와 transition이 동시에 업데이트가 되지 않아서, 두 번 수행하게끔 구성하였습니다.

import json
import datetime
import requests
from requests.auth import HTTPBasicAuth

def update_summary(event, transition_id, url, headers, auth):
    #SET SUMMARY
    build_info = event['params']['header']['buildinfo'].split('/')
    build_name = build_info[0]
    build_num = build_info[1]
    
    if transition_id == "31":
        summary = build_name + " " + build_num + " [배포 완료]"
    else:
        summary = build_name + " " + build_num + " [배포 반려]"
    print(summary)
    
    payload = json.dumps({
        "fields": {
            "summary": summary
        }
    })
    
    response = requests.request(
       "PUT",
       url,
       data=payload,
       headers=headers,
       auth=auth
    )
    
    print("summary result")
    print(response.text)
    
def update_transistion(transition_id, url, headers, auth):
    url += "/transitions"
    
    payload = json.dumps({
        "transition": {
            "id": transition_id
        }
    })
    
    response = requests.request(
       "POST",
       url,
       data=payload,
       headers=headers,
       auth=auth
    )
    
    print("transitions reulst")
    print(response.text)
    
def lambda_handler(event, context):
    #SET URL
    issue_id = event['params']['header']['x-issue-id']
    transition_id = event['params']['header']['x-transition-id']
    jira_url = "{JIRA URL}"
    api_url = "/rest/api/2/issue/"
    url = jira_url + api_url + issue_id
    
    #SET AUTH
    auth = HTTPBasicAuth("{id}", "{pw}")
    
    #SET HEADER
    headers = {
       "Accept": "application/json",
       "Content-Type": "application/json"
    }

    update_summary(event, transition_id, url, headers, auth)
    update_transistion(transition_id, url, headers, auth)

 

자 이제 모두 구성이 끝났습니다.

 

다음 게시글에서 젠킨스 파이프라인 코드를 작성하여서 돌려보도록 하겠습니다.