Run pre-commit hooks over existing codebase

Co-Authored-By: Ben Phelps <ben@phelps.io>
This commit is contained in:
shamoon 2023-10-17 23:26:55 -07:00
parent fa50bbad9c
commit 19c25713c4
387 changed files with 4785 additions and 4109 deletions

View file

@ -1,35 +1,34 @@
import path from "path";
import fs from "fs";
import { CONF_DIR } from "utils/config/config";
import createLogger from "utils/logger";
const logger = createLogger("configFileService");
/**
* @param {import("next").NextApiRequest} req
* @param {import("next").NextApiResponse} res
*/
export default async function handler(req, res) {
const { path: relativePath } = req.query;
// only two supported files, for now
if (!['custom.css', 'custom.js'].includes(relativePath))
{
return res.status(422).end('Unsupported file');
}
const filePath = path.join(CONF_DIR, relativePath);
try {
// Read the content of the file or return empty content
const fileContent = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : '';
// hard-coded since we only support two known files for now
const mimeType = (relativePath === 'custom.css') ? 'text/css' : 'text/javascript';
res.setHeader('Content-Type', mimeType);
return res.status(200).send(fileContent);
} catch (error) {
logger.error(error);
return res.status(500).end('Internal Server Error');
}
}
import path from "path";
import fs from "fs";
import { CONF_DIR } from "utils/config/config";
import createLogger from "utils/logger";
const logger = createLogger("configFileService");
/**
* @param {import("next").NextApiRequest} req
* @param {import("next").NextApiResponse} res
*/
export default async function handler(req, res) {
const { path: relativePath } = req.query;
// only two supported files, for now
if (!["custom.css", "custom.js"].includes(relativePath)) {
return res.status(422).end("Unsupported file");
}
const filePath = path.join(CONF_DIR, relativePath);
try {
// Read the content of the file or return empty content
const fileContent = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf-8") : "";
// hard-coded since we only support two known files for now
const mimeType = relativePath === "custom.css" ? "text/css" : "text/javascript";
res.setHeader("Content-Type", mimeType);
return res.status(200).send(fileContent);
} catch (error) {
logger.error(error);
return res.status(500).end("Internal Server Error");
}
}

View file

@ -44,7 +44,8 @@ export default async function handler(req, res) {
// Try with a service deployed in Docker Swarm, if enabled
if (dockerArgs.swarm) {
const tasks = await docker.listTasks({
const tasks = await docker
.listTasks({
filters: {
service: [containerName],
// A service can have several offline containers, so we only look for an active one.
@ -55,10 +56,10 @@ export default async function handler(req, res) {
// TODO: Show the result for all replicas/containers?
// We can only get stats for 'local' containers so try to find one
const localContainerIDs = containers.map(c => c.Id);
const task = tasks.find(t => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0);
const localContainerIDs = containers.map((c) => c.Id);
const task = tasks.find((t) => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0);
const taskContainerId = task?.Status?.ContainerStatus?.ContainerID;
if (taskContainerId) {
try {
const container = docker.getContainer(taskContainerId);
@ -69,8 +70,8 @@ export default async function handler(req, res) {
});
} catch (e) {
return res.status(200).json({
error: "Unable to retrieve stats"
})
error: "Unable to retrieve stats",
});
}
}
}
@ -81,7 +82,7 @@ export default async function handler(req, res) {
} catch (e) {
logger.error(e);
return res.status(500).send({
error: {message: e?.message ?? "Unknown error"},
error: { message: e?.message ?? "Unknown error" },
});
}
}

View file

@ -44,7 +44,9 @@ export default async function handler(req, res) {
}
if (dockerArgs.swarm) {
const serviceInfo = await docker.getService(containerName).inspect()
const serviceInfo = await docker
.getService(containerName)
.inspect()
.catch(() => undefined);
if (!serviceInfo) {
@ -77,15 +79,16 @@ export default async function handler(req, res) {
}
} else {
// Global service, prefer 'local' containers
const localContainerIDs = containers.map(c => c.Id);
const task = tasks.find(t => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0);
const localContainerIDs = containers.map((c) => c.Id);
const task =
tasks.find((t) => localContainerIDs.includes(t.Status?.ContainerStatus?.ContainerID)) ?? tasks.at(0);
const taskContainerId = task?.Status?.ContainerStatus?.ContainerID;
if (taskContainerId) {
try {
const container = docker.getContainer(taskContainerId);
const info = await container.inspect();
return res.status(200).json({
status: info.State.Status,
health: info.State.Health?.Status,
@ -93,8 +96,8 @@ export default async function handler(req, res) {
} catch (e) {
if (task) {
return res.status(200).json({
status: task.Status.State
})
status: task.Status.State,
});
}
}
}
@ -107,7 +110,7 @@ export default async function handler(req, res) {
} catch (e) {
logger.error(e);
return res.status(500).send({
error: {message: e?.message ?? "Unknown error"},
error: { message: e?.message ?? "Unknown error" },
});
}
}

View file

@ -4,7 +4,15 @@ import { readFileSync } from "fs";
import checkAndCopyConfig, { CONF_DIR } from "utils/config/config";
const configs = ["docker.yaml", "settings.yaml", "services.yaml", "bookmarks.yaml", "widgets.yaml", "custom.css", "custom.js"];
const configs = [
"docker.yaml",
"settings.yaml",
"services.yaml",
"bookmarks.yaml",
"widgets.yaml",
"custom.css",
"custom.js",
];
function hash(buffer) {
const hashSum = createHash("sha256");
@ -20,7 +28,7 @@ export default async function handler(req, res) {
});
// set to date by docker entrypoint, will force revalidation between restarts/recreates
const buildTime = process.env.HOMEPAGE_BUILDTIME?.length ? process.env.HOMEPAGE_BUILDTIME : '';
const buildTime = process.env.HOMEPAGE_BUILDTIME?.length ? process.env.HOMEPAGE_BUILDTIME : "";
const combinedHash = hash(hashes.join("") + buildTime);

View file

@ -13,7 +13,7 @@ export default async function handler(req, res) {
const [namespace, appName] = service;
if (!namespace && !appName) {
res.status(400).send({
error: "kubernetes query parameters are required"
error: "kubernetes query parameters are required",
});
return;
}
@ -23,13 +23,14 @@ export default async function handler(req, res) {
const kc = getKubeConfig();
if (!kc) {
res.status(500).send({
error: "No kubernetes configuration"
error: "No kubernetes configuration",
});
return;
}
const coreApi = kc.makeApiClient(CoreV1Api);
const metricsApi = new Metrics(kc);
const podsResponse = await coreApi.listNamespacedPod(namespace, null, null, null, null, labelSelector)
const podsResponse = await coreApi
.listNamespacedPod(namespace, null, null, null, null, labelSelector)
.then((response) => response.body)
.catch((err) => {
logger.error("Error getting pods: %d %s %s", err.statusCode, err.body, err.response);
@ -37,7 +38,7 @@ export default async function handler(req, res) {
});
if (!podsResponse) {
res.status(500).send({
error: "Error communicating with kubernetes"
error: "Error communicating with kubernetes",
});
return;
}
@ -63,33 +64,36 @@ export default async function handler(req, res) {
});
});
const podStatsList = await Promise.all(pods.map(async (pod) => {
let depMem = 0;
let depCpu = 0;
const podMetrics = await metricsApi.getPodMetrics(namespace, pod.metadata.name)
.then((response) => response)
.catch((err) => {
// 404 generally means that the metrics have not been populated yet
if (err.statusCode !== 404) {
logger.error("Error getting pod metrics: %d %s %s", err.statusCode, err.body, err.response);
}
return null;
});
if (podMetrics) {
podMetrics.containers.forEach((container) => {
depMem += parseMemory(container.usage.memory);
depCpu += parseCpu(container.usage.cpu);
});
}
return {
mem: depMem,
cpu: depCpu
};
}));
const podStatsList = await Promise.all(
pods.map(async (pod) => {
let depMem = 0;
let depCpu = 0;
const podMetrics = await metricsApi
.getPodMetrics(namespace, pod.metadata.name)
.then((response) => response)
.catch((err) => {
// 404 generally means that the metrics have not been populated yet
if (err.statusCode !== 404) {
logger.error("Error getting pod metrics: %d %s %s", err.statusCode, err.body, err.response);
}
return null;
});
if (podMetrics) {
podMetrics.containers.forEach((container) => {
depMem += parseMemory(container.usage.memory);
depCpu += parseCpu(container.usage.cpu);
});
}
return {
mem: depMem,
cpu: depCpu,
};
}),
);
const stats = {
mem: 0,
cpu: 0
}
cpu: 0,
};
podStatsList.forEach((podStat) => {
stats.mem += podStat.mem;
stats.cpu += podStat.cpu;
@ -99,12 +103,12 @@ export default async function handler(req, res) {
stats.cpuUsage = cpuLimit ? stats.cpu / cpuLimit : 0;
stats.memUsage = memLimit ? stats.mem / memLimit : 0;
res.status(200).json({
stats
stats,
});
} catch (e) {
logger.error(e);
res.status(500).send({
error: "unknown error"
error: "unknown error",
});
}
}

View file

@ -6,7 +6,7 @@ import createLogger from "../../../../utils/logger";
const logger = createLogger("kubernetesStatusService");
export default async function handler(req, res) {
const APP_LABEL = "app.kubernetes.io/name";
const APP_LABEL = "app.kubernetes.io/name";
const { service, podSelector } = req.query;
const [namespace, appName] = service;
@ -21,12 +21,13 @@ export default async function handler(req, res) {
const kc = getKubeConfig();
if (!kc) {
res.status(500).send({
error: "No kubernetes configuration"
error: "No kubernetes configuration",
});
return;
}
const coreApi = kc.makeApiClient(CoreV1Api);
const podsResponse = await coreApi.listNamespacedPod(namespace, null, null, null, null, labelSelector)
const podsResponse = await coreApi
.listNamespacedPod(namespace, null, null, null, null, labelSelector)
.then((response) => response.body)
.catch((err) => {
logger.error("Error getting pods: %d %s %s", err.statusCode, err.body, err.response);
@ -34,7 +35,7 @@ export default async function handler(req, res) {
});
if (!podsResponse) {
res.status(500).send({
error: "Error communicating with kubernetes"
error: "Error communicating with kubernetes",
});
return;
}
@ -46,7 +47,7 @@ export default async function handler(req, res) {
});
return;
}
const someReady = pods.find(pod => pod.status.phase === "Running");
const someReady = pods.find((pod) => pod.status.phase === "Running");
const allReady = pods.every((pod) => pod.status.phase === "Running");
let status = "down";
if (allReady) {
@ -55,7 +56,7 @@ export default async function handler(req, res) {
status = "partial";
}
res.status(200).json({
status
status,
});
} catch (e) {
logger.error(e);

View file

@ -7,46 +7,46 @@ import { httpProxy } from "utils/proxy/http";
const logger = createLogger("ping");
export default async function handler(req, res) {
const { group, service } = req.query;
const serviceItem = await getServiceItem(group, service);
if (!serviceItem) {
logger.debug(`No service item found for group ${group} named ${service}`);
return res.status(400).send({
error: "Unable to find service, see log for details.",
});
const { group, service } = req.query;
const serviceItem = await getServiceItem(group, service);
if (!serviceItem) {
logger.debug(`No service item found for group ${group} named ${service}`);
return res.status(400).send({
error: "Unable to find service, see log for details.",
});
}
const { ping: pingURL } = serviceItem;
if (!pingURL) {
logger.debug("No ping URL specified");
return res.status(400).send({
error: "No ping URL given",
});
}
try {
let startTime = performance.now();
let [status] = await httpProxy(pingURL, {
method: "HEAD",
});
let endTime = performance.now();
if (status > 403) {
// try one more time as a GET in case HEAD is rejected for whatever reason
startTime = performance.now();
[status] = await httpProxy(pingURL);
endTime = performance.now();
}
const { ping: pingURL } = serviceItem;
if (!pingURL) {
logger.debug("No ping URL specified");
return res.status(400).send({
error: "No ping URL given",
});
}
try {
let startTime = performance.now();
let [status] = await httpProxy(pingURL, {
method: "HEAD"
});
let endTime = performance.now();
if (status > 403) {
// try one more time as a GET in case HEAD is rejected for whatever reason
startTime = performance.now();
[status] = await httpProxy(pingURL);
endTime = performance.now();
}
return res.status(200).json({
status,
latency: endTime - startTime
});
} catch (e) {
logger.debug("Error attempting ping: %s", JSON.stringify(e));
return res.status(400).send({
error: 'Error attempting ping, see logs.',
});
}
return res.status(200).json({
status,
latency: endTime - startTime,
});
} catch (e) {
logger.debug("Error attempting ping: %s", JSON.stringify(e));
return res.status(400).send({
error: "Error attempting ping, see logs.",
});
}
}

View file

@ -44,13 +44,13 @@ export default async function handler(req, res) {
if (req.query.query && (mappingParams || optionalParams)) {
const queryParams = JSON.parse(req.query.query);
let filteredOptionalParams = []
if (optionalParams) filteredOptionalParams = optionalParams.filter(p => queryParams[p] !== undefined);
let filteredOptionalParams = [];
if (optionalParams) filteredOptionalParams = optionalParams.filter((p) => queryParams[p] !== undefined);
let params = [];
if (mappingParams) params = params.concat(mappingParams);
if (filteredOptionalParams) params = params.concat(filteredOptionalParams);
const query = new URLSearchParams(params.map((p) => [p, queryParams[p]]));
req.query.endpoint = `${req.query.endpoint}?${query}`;
}

View file

@ -15,23 +15,25 @@ async function retrieveFromGlancesAPI(privateWidgetOptions, endpoint) {
const apiUrl = `${url}/api/3/${endpoint}`;
const headers = {
"Accept-Encoding": "application/json"
"Accept-Encoding": "application/json",
};
if (privateWidgetOptions.username && privateWidgetOptions.password) {
headers.Authorization = `Basic ${Buffer.from(`${privateWidgetOptions.username}:${privateWidgetOptions.password}`).toString("base64")}`
headers.Authorization = `Basic ${Buffer.from(
`${privateWidgetOptions.username}:${privateWidgetOptions.password}`,
).toString("base64")}`;
}
const params = { method: "GET", headers };
const [status, , data] = await httpProxy(apiUrl, params);
if (status === 401) {
errorMessage = `Authorization failure getting data from glances API. Data: ${data.toString()}`
errorMessage = `Authorization failure getting data from glances API. Data: ${data.toString()}`;
logger.error(errorMessage);
throw new Error(errorMessage);
}
if (status !== 200) {
errorMessage = `HTTP ${status} getting data from glances API. Data: ${data.toString()}`
errorMessage = `HTTP ${status} getting data from glances API. Data: ${data.toString()}`;
logger.error(errorMessage);
throw new Error(errorMessage);
}
@ -52,7 +54,7 @@ export default async function handler(req, res) {
cpu: cpuData,
load: loadData,
mem: memoryData,
}
};
// Disabled by default, dont call unless needed
if (includeUptime) {

View file

@ -11,13 +11,14 @@ export default async function handler(req, res) {
const kc = getKubeConfig();
if (!kc) {
return res.status(500).send({
error: "No kubernetes configuration"
error: "No kubernetes configuration",
});
}
const coreApi = kc.makeApiClient(CoreV1Api);
const metricsApi = new Metrics(kc);
const nodes = await coreApi.listNode()
const nodes = await coreApi
.listNode()
.then((response) => response.body)
.catch((error) => {
logger.error("Error getting ingresses: %d %s %s", error.statusCode, error.body, error.response);
@ -25,7 +26,7 @@ export default async function handler(req, res) {
});
if (!nodes) {
return res.status(500).send({
error: "unknown error"
error: "unknown error",
});
}
let cpuTotal = 0;
@ -37,16 +38,18 @@ export default async function handler(req, res) {
nodes.items.forEach((node) => {
const cpu = Number.parseInt(node.status.capacity.cpu, 10);
const mem = parseMemory(node.status.capacity.memory);
const ready = node.status.conditions.filter(condition => condition.type === "Ready" && condition.status === "True").length > 0;
const ready =
node.status.conditions.filter((condition) => condition.type === "Ready" && condition.status === "True").length >
0;
nodeMap[node.metadata.name] = {
name: node.metadata.name,
ready,
cpu: {
total: cpu
total: cpu,
},
memory: {
total: mem
}
total: mem,
},
};
cpuTotal += cpu;
memTotal += mem;
@ -68,7 +71,7 @@ export default async function handler(req, res) {
} catch (error) {
logger.error("Error getting metrics, ensure you have metrics-server installed: s", JSON.stringify(error));
return res.status(500).send({
error: "Error getting metrics, check logs for more details"
error: "Error getting metrics, check logs for more details",
});
}
@ -76,24 +79,24 @@ export default async function handler(req, res) {
cpu: {
load: cpuUsage,
total: cpuTotal,
percent: (cpuUsage / cpuTotal) * 100
percent: (cpuUsage / cpuTotal) * 100,
},
memory: {
used: memUsage,
total: memTotal,
free: (memTotal - memUsage),
percent: (memUsage / memTotal) * 100
}
free: memTotal - memUsage,
percent: (memUsage / memTotal) * 100,
},
};
return res.status(200).json({
cluster,
nodes: Object.entries(nodeMap).map(([name, node]) => ({ name, ...node }))
nodes: Object.entries(nodeMap).map(([name, node]) => ({ name, ...node })),
});
} catch (e) {
logger.error("exception %s", e);
return res.status(500).send({
error: "unknown error"
error: "unknown error",
});
}
}

View file

@ -47,7 +47,7 @@ function parseLonghornData(data) {
export default async function handler(req, res) {
const settings = getSettings();
const longhornSettings = settings?.providers?.longhorn || {};
const {url, username, password} = longhornSettings;
const { url, username, password } = longhornSettings;
if (!url) {
const errorMessage = "Missing Longhorn URL";
@ -57,10 +57,10 @@ export default async function handler(req, res) {
const apiUrl = `${url}/v1/nodes`;
const headers = {
"Accept-Encoding": "application/json"
"Accept-Encoding": "application/json",
};
if (username && password) {
headers.Authorization = `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`
headers.Authorization = `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`;
}
const params = { method: "GET", headers };

View file

@ -3,7 +3,7 @@ import cachedFetch from "utils/proxy/cached-fetch";
export default async function handler(req, res) {
const { latitude, longitude, units, cache, timezone } = req.query;
const degrees = units === "imperial" ? "fahrenheit" : "celsius";
const timezeone = timezone ?? 'auto'
const timezeone = timezone ?? "auto";
const apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&daily=sunrise,sunset&current_weather=true&temperature_unit=${degrees}&timezone=${timezeone}`;
return res.send(await cachedFetch(apiUrl, cache));
}
}

View file

@ -1,6 +1,6 @@
import { existsSync } from "fs";
const si = require('systeminformation');
const si = require("systeminformation");
export default async function handler(req, res) {
const { type, target } = req.query;
@ -25,7 +25,7 @@ export default async function handler(req, res) {
const fsSize = await si.fsSize();
return res.status(200).json({
drive: fsSize.find(fs => fs.mount === target) ?? fsSize.find(fs => fs.mount === "/")
drive: fsSize.find((fs) => fs.mount === target) ?? fsSize.find((fs) => fs.mount === "/"),
});
}
@ -44,7 +44,7 @@ export default async function handler(req, res) {
if (type === "uptime") {
const timeData = await si.time();
return res.status(200).json({
uptime: timeData.uptime
uptime: timeData.uptime,
});
}