mirror of
https://github.com/rajnandan1/kener.git
synced 2026-01-01 23:19:44 -06:00
400 lines
13 KiB
JavaScript
400 lines
13 KiB
JavaScript
// @ts-nocheck
|
|
import axios from "axios";
|
|
import { GetMinuteStartNowTimestampUTC } from "./tool.js";
|
|
import { marked } from "marked";
|
|
const GH_TOKEN = process.env.GH_TOKEN;
|
|
const GhnotconfireguredMsg = "owner or repo or GH_TOKEN is undefined. Read the docs to configure github: https://kener.ing/docs#h2github-setup";
|
|
/**
|
|
* @param {any} url
|
|
*/
|
|
function getAxiosOptions(url) {
|
|
const options = {
|
|
url: url,
|
|
method: "GET",
|
|
headers: {
|
|
Accept: "application/vnd.github+json",
|
|
Authorization: "Bearer " + GH_TOKEN,
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
},
|
|
};
|
|
return options;
|
|
}
|
|
function postAxiosOptions(url, data) {
|
|
const options = {
|
|
url: url,
|
|
method: "POST",
|
|
headers: {
|
|
Accept: "application/vnd.github+json",
|
|
Authorization: "Bearer " + GH_TOKEN,
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
},
|
|
data: data,
|
|
};
|
|
return options;
|
|
}
|
|
function patchAxiosOptions(url, data) {
|
|
const options = {
|
|
url: url,
|
|
method: "PATCH",
|
|
headers: {
|
|
Accept: "application/vnd.github+json",
|
|
Authorization: "Bearer " + GH_TOKEN,
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
},
|
|
data: data,
|
|
};
|
|
return options;
|
|
}
|
|
|
|
const GetAllGHLabels = async function (owner, repo) {
|
|
if (owner === undefined || repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return [];
|
|
}
|
|
const options = getAxiosOptions(`https://api.github.com/repos/${owner}/${repo}/labels?per_page=1000`);
|
|
|
|
let labels = [];
|
|
try {
|
|
const response = await axios.request(options);
|
|
labels = response.data.map((label) => label.name);
|
|
} catch (error) {
|
|
console.log(error.response?.data);
|
|
return [];
|
|
}
|
|
return labels;
|
|
};
|
|
function generateRandomColor() {
|
|
var randomColor = Math.floor(Math.random() * 16777215).toString(16);
|
|
return randomColor;
|
|
//random color will be freshly served
|
|
}
|
|
const CreateGHLabel = async function (owner, repo, label, description, color) {
|
|
if (owner === undefined || repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
if (color === undefined) {
|
|
color = generateRandomColor();
|
|
}
|
|
|
|
const options = postAxiosOptions(`https://api.github.com/repos/${owner}/${repo}/labels`, {
|
|
name: label,
|
|
color: color,
|
|
description: description,
|
|
});
|
|
try {
|
|
const response = await axios.request(options);
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
};
|
|
const GetStartTimeFromBody = function (text) {
|
|
const pattern = /\[start_datetime:(\d+)\]/;
|
|
|
|
const matches = pattern.exec(text);
|
|
|
|
if (matches) {
|
|
const timestamp = matches[1];
|
|
return parseInt(timestamp);
|
|
}
|
|
return null;
|
|
};
|
|
const GetEndTimeFromBody = function (text) {
|
|
const pattern = /\[end_datetime:(\d+)\]/;
|
|
|
|
const matches = pattern.exec(text);
|
|
|
|
if (matches) {
|
|
const timestamp = matches[1];
|
|
return parseInt(timestamp);
|
|
}
|
|
return null;
|
|
};
|
|
const GetIncidentByNumber = async function (githubConfig, incidentNumber) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${incidentNumber}`;
|
|
const options = getAxiosOptions(url);
|
|
try {
|
|
const response = await axios.request(options);
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.message, options, url);
|
|
return null;
|
|
}
|
|
};
|
|
const GetIncidents = async function (tagName, githubConfig, state = "all") {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return [];
|
|
}
|
|
if (tagName === undefined) {
|
|
return [];
|
|
}
|
|
const since = GetMinuteStartNowTimestampUTC() - githubConfig.incidentSince * 60 * 60;
|
|
const sinceISO = new Date(since * 1000).toISOString();
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues?state=${state}&labels=${tagName},incident&sort=created&direction=desc&since=${sinceISO}`;
|
|
const options = getAxiosOptions(url);
|
|
try {
|
|
const response = await axios.request(options);
|
|
let issues = response.data;
|
|
//issues.createAt should be after sinceISO
|
|
issues = issues.filter((issue) => {
|
|
return new Date(issue.created_at) >= new Date(sinceISO);
|
|
});
|
|
return issues;
|
|
} catch (error) {
|
|
console.log(error.response?.data);
|
|
return [];
|
|
}
|
|
};
|
|
const GetOpenIncidents = async function (githubConfig) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return [];
|
|
}
|
|
|
|
const since = GetMinuteStartNowTimestampUTC() - githubConfig.incidentSince * 60 * 60;
|
|
const sinceISO = new Date(since * 1000).toISOString();
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues?state=open&labels=incident&sort=created&direction=desc&since=${sinceISO}`;
|
|
const options = getAxiosOptions(url);
|
|
try {
|
|
const response = await axios.request(options);
|
|
let issues = response.data;
|
|
//issues.createAt should be after sinceISO
|
|
issues = issues.filter((issue) => {
|
|
return new Date(issue.created_at) >= new Date(sinceISO);
|
|
});
|
|
return issues;
|
|
} catch (error) {
|
|
console.log(error.response?.data);
|
|
return [];
|
|
}
|
|
};
|
|
function FilterAndInsertMonitorInIncident(openIncidentsReduced, monitorsActive) {
|
|
let openIncidentExploded = [];
|
|
for (let i = 0; i < openIncidentsReduced.length; i++) {
|
|
for (let j = 0; j < monitorsActive.length; j++) {
|
|
if (openIncidentsReduced[i].labels.includes(monitorsActive[j].tag)) {
|
|
let incident = JSON.parse(JSON.stringify(openIncidentsReduced[i]));
|
|
incident.monitor = {
|
|
name: monitorsActive[j].name,
|
|
tag: monitorsActive[j].tag,
|
|
image: monitorsActive[j].image,
|
|
description: monitorsActive[j].description,
|
|
};
|
|
openIncidentExploded.push(incident);
|
|
}
|
|
}
|
|
}
|
|
return openIncidentExploded;
|
|
}
|
|
function Mapper(issue) {
|
|
const html = marked.parse(issue.body);
|
|
|
|
//convert issue.created_at from iso to timestamp UTC minutes
|
|
const issueCreatedAt = new Date(issue.created_at);
|
|
const issueCreatedAtTimestamp = issueCreatedAt.getTime() / 1000;
|
|
|
|
//convert issue.closed_at from iso to timestamp UTC minutes
|
|
let issueClosedAtTimestamp = null;
|
|
if (issue.closed_at !== null) {
|
|
const issueClosedAt = new Date(issue.closed_at);
|
|
issueClosedAtTimestamp = issueClosedAt.getTime() / 1000;
|
|
}
|
|
|
|
|
|
let labels = issue.labels.map(function (label) {
|
|
return label.name;
|
|
});
|
|
//find and add monitors tag in labels
|
|
|
|
let res = {
|
|
title: issue.title,
|
|
incident_start_time: GetStartTimeFromBody(issue.body) || issueCreatedAtTimestamp,
|
|
incident_end_time: GetEndTimeFromBody(issue.body) || issueClosedAtTimestamp,
|
|
number: issue.number,
|
|
body: html,
|
|
created_at: issue.created_at,
|
|
updated_at: issue.updated_at,
|
|
collapsed: true,
|
|
// @ts-ignore
|
|
state: issue.state,
|
|
closed_at: issue.closed_at,
|
|
// @ts-ignore
|
|
labels: labels,
|
|
html_url: issue.html_url,
|
|
comments: [],
|
|
};
|
|
|
|
return res;
|
|
}
|
|
async function GetCommentsForIssue(issueID, githubConfig) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return [];
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${issueID}/comments`;
|
|
try {
|
|
const response = await axios.request(getAxiosOptions(url));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return [];
|
|
}
|
|
}
|
|
async function CreateIssue(githubConfig, issueTitle, issueBody, issueLabels) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues`;
|
|
try {
|
|
const payload = {
|
|
title: issueTitle,
|
|
body: issueBody,
|
|
labels: issueLabels,
|
|
};
|
|
const response = await axios.request(postAxiosOptions(url, payload));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
}
|
|
async function UpdateIssue(githubConfig, incidentNumber, issueTitle, issueBody, issueLabels, state = "open") {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${incidentNumber}`;
|
|
try {
|
|
const payload = {
|
|
title: issueTitle,
|
|
body: issueBody,
|
|
labels: issueLabels,
|
|
state: state,
|
|
};
|
|
const response = await axios.request(patchAxiosOptions(url, payload));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
}
|
|
async function CloseIssue(githubConfig, incidentNumber) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${incidentNumber}`;
|
|
try {
|
|
const payload = {
|
|
state: "closed"
|
|
};
|
|
const response = await axios.request(patchAxiosOptions(url, payload));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
}
|
|
async function AddComment(githubConfig, incidentNumber, commentBody) {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${incidentNumber}/comments`;
|
|
try {
|
|
const payload = {
|
|
body: commentBody,
|
|
};
|
|
const response = await axios.request(postAxiosOptions(url, payload));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
}
|
|
//update issue labels
|
|
async function UpdateIssueLabels(githubConfig, incidentNumber, issueLabels, body, state = "open") {
|
|
if (githubConfig.owner === undefined || githubConfig.repo === undefined || GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
const url = `https://api.github.com/repos/${githubConfig.owner}/${githubConfig.repo}/issues/${incidentNumber}`;
|
|
try {
|
|
const payload = {
|
|
labels: issueLabels,
|
|
body: body,
|
|
state: state,
|
|
};
|
|
const response = await axios.request(patchAxiosOptions(url, payload));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
//search issue
|
|
async function SearchIssue(query, page, per_page) {
|
|
if (GH_TOKEN === undefined) {
|
|
console.log(GhnotconfireguredMsg);
|
|
return null;
|
|
}
|
|
|
|
const searchQuery =
|
|
query
|
|
.filter(function (q) {
|
|
if (q == "" || q === undefined || q === null) {
|
|
return false;
|
|
}
|
|
const qs = q.split(":");
|
|
if (qs.length < 2) {
|
|
return false;
|
|
}
|
|
if (qs[1] === "" || qs[1] === undefined || qs[1] === null) {
|
|
return false;
|
|
}
|
|
return true;
|
|
})
|
|
.join(" ")
|
|
|
|
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(
|
|
searchQuery
|
|
)}&per_page=${per_page}&page=${page}`;
|
|
|
|
try {
|
|
const response = await axios.request(getAxiosOptions(url));
|
|
return response.data;
|
|
} catch (error) {
|
|
console.log(error.response.data);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
|
|
export {
|
|
GetAllGHLabels,
|
|
CreateGHLabel,
|
|
GetIncidents,
|
|
GetStartTimeFromBody,
|
|
GetEndTimeFromBody,
|
|
GetCommentsForIssue,
|
|
Mapper,
|
|
CreateIssue,
|
|
AddComment,
|
|
GetIncidentByNumber,
|
|
UpdateIssueLabels,
|
|
UpdateIssue,
|
|
CloseIssue,
|
|
GetOpenIncidents,
|
|
FilterAndInsertMonitorInIncident,
|
|
SearchIssue,
|
|
};
|