CI+CD/Jenkins 활용

Jenkins 활용 - 3 (젠킨스 Api로 데이터 불러오기 + CORS 에러 해결)

salzzak 2024. 10. 2. 18:11
728x90

- jenkins api 토큰 발급

http://<jenkins-server>/crumbIssuer/api/json

 

- 원격빌드

http://<jenkins-server>/job/<job-name>build

 

- Jenkins 대시보드

http://<jenkins-server>/api/json

 

- 특정 Job

http://<jenkins-server>/job/<job-name>api/json

 

- 특정 build

http://<jenkins-server>/job/<job-name>/<build-number>/api/json

 

- 특정 build Report

http://<jenkins-server>/job/<job-name>/<build-number>/testReport/api/json

 

 

특정 build Report API 호출 시, Json 포맷으로 결과값 노출된다.

Visualize 탭에서는 아래와 같이 결과값 표기된다.

 

 

위와 같이 원격 + Postman 으로 API 발송시에는 정상 요청 / 응답 동작된다.

 

이어서 웹페이지를 만들고 버튼을 눌러서 요청을 하도록 구현해보면...

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>API 호출 예제</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .container {
            max-width: 600px;
            margin: 50px auto;
            text-align: center;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 5px;
        }
        button:hover {
            background-color: #0056B3;
        }
        .result {
            margin-top: 20px;
            padding: 10px;
            border: 1px solid #ddd;
            background-color: #F4F4F4;
        }
        .result p {
            margin: 0;
            padding: 0;
            word-wrap: break-word;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>API 호출 예제</h1>
        <button id="testResult">testResult</button>
        <button id="runBuild">runBuild</button>
        <button id="jobResult">jobResult</button>
        <div class="result" id="result">
            <p>API 응답이 여기에 표시됩니다.</p>
        </div>
    </div>
    <script>
        const myHeaders = new Headers();
                myHeaders.append("Jenkins-Crumb", "a8be5a51a181c08c1a496c76eb9a851c1961f10f2bec01ce43bc7bbeea9b535a");
                myHeaders.append("Authorization", "Basic " + btoa('cjconnect:1118296fcd85fcb1756021b1b2562b12e1'));
                const requestOptions = {
                    method: "POST",
                    headers: myHeaders,
                    redirect: "follow"
                };

        var host = "localhost"
        var jobName = "dashboard_test_01"
        var jobNumber = "1"

        var testResult = `http://${host}:8080/job/${jobName}/${jobNumber}/testReport/api/json`
        var runBuild = `http://${host}:8080/job/${jobName}/build`
        var jobResult = `http://${host}:8080/job/${jobName}/api/json`
      
        document.getElementById('testResult').addEventListener('click', () => callApi(testResult));
        document.getElementById('runBuild').addEventListener('click', () => callApi(runBuild));
        document.getElementById('jobResult').addEventListener('click', () => callApi(jobResult));
        async function callApi(url) {
            // const myHeaders = new Headers();
            const myHeaders = new Headers();
            myHeaders.append("Jenkins-Crumb", "a8be5a51a181c08c1a496c76eb9a851c1961f10f2bec01ce43bc7bbeea9b535a");
            myHeaders.append("Authorization", "Basic " + btoa('cjconnect:1118296fcd85fcb1756021b1b2562b12e1'));
            const requestOptions = {
                method: "POST",
                headers: myHeaders,
                redirect: "follow"
            };
            try {
                const response = await fetch(url, requestOptions);
                if (!response.ok) {
                    throw new Error('네트워크 응답이 올바르지 않습니다');
                }
                const text = await response.text(); // response의 텍스트를 먼저 읽어옵니다
                if (!text) {
                    throw new Error('응답이 비어 있습니다');
                }
                const data = await JSON.parse(text);
                // 응답 데이터를 화면에 표시
                displayResult(data);
            } catch (error) {
                console.error('API 호출 중 오류가 발생했습니다:', error);
                document.getElementById('result').innerHTML = '<p>API 호출 중 오류가 발생했습니다: ' + error.message + '</p>';
            }
        }
        function displayResult(data) {
            const resultDiv = document.getElementById('result');
            resultDiv.innerHTML = ''; // 기존 내용 초기화
            const jsonString = JSON.stringify(data, null, 2); // 데이터를 JSON 문자열로 변환
            const preTag = document.createElement('pre'); // 가독성을 위한 <pre> 태그 사용
            preTag.textContent = jsonString;
            resultDiv.appendChild(preTag);
        }
    </script>
</body>
</html>

 

 

버튼 클릭 시(API 요청 시) CORS policy 에러가 발생한다.

 

삽질 #1 (넘어가세요)

더보기

Chatgpt 왈... (이하 GPT가 시키는대로 해보고 작성)

 

 

Server 에 Node.js 가 깔려있는 상태 전제하에

 

프로젝트 폴더에서 

npm install express 명령어 실행

node_modules 폴더가 생긴다. (Express 관련 패키지 존재)

 

 

CORS 패키지를 설치한다.

npm install cors 

 

 

server.js 파일 생성 후 아래와 같이 코드를 넣어준다.

// server.js

const express = require('express');
const cors = require('cors');
const app = express();

// CORS 설정
app.use(cors()); // 모든 출처에서 요청을 허용

// 간단한 API 엔드포인트
app.get('/', (req, res) => {
    res.send('Node.js 서버가 정상적으로 동작하고 있습니다!');
});

// 서버가 3000번 포트에서 실행되도록 설정
app.listen(3000, () => {
    console.log('서버가 http://localhost:3000 에서 실행 중입니다.');
});

 

 

이런 모양새

 

npm install -g nodemon 서버를 실행하면, 파일을 수정할 때마다 자동으로 서버가 재시작되는 nodemon 설치

(기존 node server.js 로 서버 실행 시, 매번 껐다 켜줘야 한다.)

 

nodemon server.js 로 서버 실행

 

 

브라우저에서 http://localhost:3000/ 접속 시 아래와 같이 노출되면 성공

 

... 이렇게 하는게 아닌것 같다.

8080 포트의

Chatgpt 왈... (이하 GPT가 시키는대로 해보고 작성)

 

 

Server 에 Node.js 가 깔려있는 상태 전제하에

 

프로젝트 폴더에서 

npm install express 명령어 실행

node_modules 폴더가 생긴다. (Express 관련 패키지 존재)

 

 

CORS 패키지를 설치한다.

npm install cors 

 

 

server.js 파일 생성 후 아래와 같이 코드를 넣어준다.

// server.js

const express = require('express');
const cors = require('cors');
const app = express();

// CORS 설정
app.use(cors()); // 모든 출처에서 요청을 허용

// 간단한 API 엔드포인트
app.get('/', (req, res) => {
    res.send('Node.js 서버가 정상적으로 동작하고 있습니다!');
});

// 서버가 3000번 포트에서 실행되도록 설정
app.listen(3000, () => {
    console.log('서버가 http://localhost:3000 에서 실행 중입니다.');
});

 

 

이런 모양새

 

npm install -g nodemon 서버를 실행하면, 파일을 수정할 때마다 자동으로 서버가 재시작되는 nodemon 설치

(기존 node server.js 로 서버 실행 시, 매번 껐다 켜줘야 한다.)

 

nodemon server.js 로 서버 실행

 

 

브라우저에서 http://localhost:3000/ 접속 시 아래와 같이 노출되면 성공

 

...

 

이렇게 하는게 아닌것 같다.

8080포트를 access-control-allow-origin 를 열어줘야하는데... 엉뚱하게 3000포트를 열어주고 있었음.
+ server.js 를 8080으로 열면 jenkins가 사용하고 있기때문에, 당연히 안됨

 

삽질 #1 이후 젠킨스 서버 (8080) 에서 access-control-allow-origin을 설정해주어야 함을 알게됨

 

Jenkins 관리 > Plugins > Available plugins > CORS support 검색 > 선택 후 Install

 

설치 후 jenkins 자동 재시작 

 

Jenkins 관리 > System > CORS Filter 영역이 생김을 알 수 있다.

위와 같이 입력

access-control-allow-headers의 경우, Postman에서 api 요청 시 넣어주었던 header 값을 입력해준다.

 

 

이후 localhost:8080/restart 에서 jenkins 재기동

 

 

이후, 아까 만든 웹페이지에서 API 호출 가능함을 알 수 있다.