mirror of
https://github.com/gethomepage/homepage.git
synced 2025-12-07 09:35:54 -08:00
refactored code to seperate kubernetes resources
This commit is contained in:
@@ -76,4 +76,6 @@ export async function checkCRD(name,kc,logger) {
|
||||
}
|
||||
|
||||
export const ANNOTATION_BASE = "gethomepage.dev";
|
||||
export const ANNOTATION_WIDGET_BASE = `${ANNOTATION_BASE}/widget.`;
|
||||
export const ANNOTATION_WIDGET_BASE = `${ANNOTATION_BASE}/widget.`;
|
||||
export const HTTPROUTE_API_GROUP = "gateway.networking.k8s.io";
|
||||
export const HTTPROUTE_API_VERSION = "v1";
|
||||
@@ -9,8 +9,6 @@ import checkAndCopyConfig, { CONF_DIR, getSettings, substituteEnvironmentVars }
|
||||
import getDockerArguments from "utils/config/docker";
|
||||
import kubernetes from "utils/kubernetes/kubernetes-export";
|
||||
import getKubeArguments from "utils/config/kubernetes";
|
||||
// import { getUrlSchema, getRouteList } from "utils/kubernetes/kubernetes-routes";
|
||||
// import { ANNOTATION_BASE, ANNOTATION_WIDGET_BASE } from "utils/config/kubernetes";
|
||||
import * as shvl from "utils/config/shvl";
|
||||
|
||||
const logger = createLogger("service-helpers");
|
||||
@@ -180,6 +178,7 @@ export async function servicesFromKubernetes() {
|
||||
return [];
|
||||
}
|
||||
|
||||
//resource lists
|
||||
const [ingressList, traefikIngressList, httpRouteList] = await Promise.all([
|
||||
kubernetes.listIngress(kubeArguments),
|
||||
kubernetes.listTraefikIngress(kubeArguments),
|
||||
@@ -195,6 +194,7 @@ export async function servicesFromKubernetes() {
|
||||
.filter(resource => kubernetes.isDiscoverable(resource, instanceName))
|
||||
.map(async (resource) => kubernetes.constructedServiceFromResource(resource)));
|
||||
|
||||
//map service groups
|
||||
const mappedServiceGroups = services.reduce((groups, serverService) => {
|
||||
let serverGroup = groups.find(group => group.name === serverService.group);
|
||||
|
||||
@@ -216,94 +216,6 @@ export async function servicesFromKubernetes() {
|
||||
return groups;
|
||||
}, []);
|
||||
|
||||
|
||||
// console.log(mappedServiceGroups);
|
||||
// const routeList = await getRouteList(ANNOTATION_BASE);
|
||||
|
||||
// if (!routeList) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// const services = await Promise.all(
|
||||
// routeList
|
||||
// .filter(
|
||||
// (route) =>
|
||||
// route.metadata.annotations &&
|
||||
// route.metadata.annotations[`${ANNOTATION_BASE}/enabled`] === "true" &&
|
||||
// (!route.metadata.annotations[`${ANNOTATION_BASE}/instance`] ||
|
||||
// route.metadata.annotations[`${ANNOTATION_BASE}/instance`] === instanceName ||
|
||||
// `${ANNOTATION_BASE}/instance.${instanceName}` in route.metadata.annotations),
|
||||
// )
|
||||
// .map(async (route) => {
|
||||
// let constructedService = {
|
||||
// app: route.metadata.annotations[`${ANNOTATION_BASE}/app`] || route.metadata.name,
|
||||
// namespace: route.metadata.namespace,
|
||||
// href: route.metadata.annotations[`${ANNOTATION_BASE}/href`] || (await getUrlSchema(route)),
|
||||
// name: route.metadata.annotations[`${ANNOTATION_BASE}/name`] || route.metadata.name,
|
||||
// group: route.metadata.annotations[`${ANNOTATION_BASE}/group`] || "Kubernetes",
|
||||
// weight: route.metadata.annotations[`${ANNOTATION_BASE}/weight`] || "0",
|
||||
// icon: route.metadata.annotations[`${ANNOTATION_BASE}/icon`] || "",
|
||||
// description: route.metadata.annotations[`${ANNOTATION_BASE}/description`] || "",
|
||||
// external: false,
|
||||
// type: "service",
|
||||
// };
|
||||
// if (route.metadata.annotations[`${ANNOTATION_BASE}/external`]) {
|
||||
// constructedService.external =
|
||||
// String(route.metadata.annotations[`${ANNOTATION_BASE}/external`]).toLowerCase() === "true";
|
||||
// }
|
||||
// if (route.metadata.annotations[`${ANNOTATION_BASE}/pod-selector`] !== undefined) {
|
||||
// constructedService.podSelector = route.metadata.annotations[`${ANNOTATION_BASE}/pod-selector`];
|
||||
// }
|
||||
// if (route.metadata.annotations[`${ANNOTATION_BASE}/ping`]) {
|
||||
// constructedService.ping = route.metadata.annotations[`${ANNOTATION_BASE}/ping`];
|
||||
// }
|
||||
// if (route.metadata.annotations[`${ANNOTATION_BASE}/siteMonitor`]) {
|
||||
// constructedService.siteMonitor = route.metadata.annotations[`${ANNOTATION_BASE}/siteMonitor`];
|
||||
// }
|
||||
// if (route.metadata.annotations[`${ANNOTATION_BASE}/statusStyle`]) {
|
||||
// constructedService.statusStyle = route.metadata.annotations[`${ANNOTATION_BASE}/statusStyle`];
|
||||
// }
|
||||
// Object.keys(route.metadata.annotations).forEach((annotation) => {
|
||||
// if (annotation.startsWith(ANNOTATION_WIDGET_BASE)) {
|
||||
// shvl.set(
|
||||
// constructedService,
|
||||
// annotation.replace(`${ANNOTATION_BASE}/`, ""),
|
||||
// route.metadata.annotations[annotation],
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
|
||||
// try {
|
||||
// constructedService = JSON.parse(substituteEnvironmentVars(JSON.stringify(constructedService)));
|
||||
// } catch (e) {
|
||||
// logger.error("Error attempting k8s environment variable substitution.");
|
||||
// logger.debug(e);
|
||||
// }
|
||||
// return constructedService;
|
||||
// }),
|
||||
// );
|
||||
|
||||
// const mappedServiceGroups = [];
|
||||
|
||||
// services.forEach((serverService) => {
|
||||
// let serverGroup = mappedServiceGroups.find((searchedGroup) => searchedGroup.name === serverService.group);
|
||||
// if (!serverGroup) {
|
||||
// mappedServiceGroups.push({
|
||||
// name: serverService.group,
|
||||
// services: [],
|
||||
// });
|
||||
// serverGroup = mappedServiceGroups[mappedServiceGroups.length - 1];
|
||||
// }
|
||||
|
||||
// const { name: serviceName, group: serverServiceGroup, ...pushedService } = serverService;
|
||||
// const result = {
|
||||
// name: serviceName,
|
||||
// ...pushedService,
|
||||
// };
|
||||
|
||||
// serverGroup.services.push(result);
|
||||
// });
|
||||
|
||||
return mappedServiceGroups;
|
||||
} catch (e) {
|
||||
if (e) logger.error(e);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
import { CustomObjectsApi, CoreV1Api } from "@kubernetes/client-node";
|
||||
|
||||
import { HTTPROUTE_API_GROUP,HTTPROUTE_API_VERSION } from "utils/config/kubernetes";
|
||||
import createLogger from "utils/logger";
|
||||
|
||||
const logger = createLogger("kubernetes-httproute-list");
|
||||
const HTTPROUTE_API_GROUP = "gateway.networking.k8s.io";
|
||||
const HTTPROUTE_API_VERSION = "v1";
|
||||
|
||||
export default async function listHttpRoute(kubeArguments) {
|
||||
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
import { CustomObjectsApi } from "@kubernetes/client-node";
|
||||
|
||||
import getKubeArguments from "utils/config/kubernetes";
|
||||
import createLogger from "utils/logger";
|
||||
|
||||
const logger = createLogger("service-helpers");
|
||||
|
||||
const kubeArguments = getKubeArguments();
|
||||
const kc = kubeArguments.config;
|
||||
|
||||
const apiGroup = "gateway.networking.k8s.io";
|
||||
const version = "v1";
|
||||
|
||||
const getSchemaFromGateway = async (gatewayRef) => {
|
||||
const crd = kc.makeApiClient(CustomObjectsApi);
|
||||
const schema = await crd
|
||||
.getNamespacedCustomObject(apiGroup, version, gatewayRef.namespace, "gateways", gatewayRef.name)
|
||||
.then((response) => {
|
||||
const listner = response.body.spec.listeners.filter((listener) => listener.name === gatewayRef.sectionName)[0];
|
||||
return listner.protocol.toLowerCase();
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error("Error getting gateways: %d %s %s", error.statusCode, error.body, error.response);
|
||||
logger.debug(error);
|
||||
return "";
|
||||
});
|
||||
return schema;
|
||||
};
|
||||
|
||||
async function getUrlFromHttpRoute(resource) {
|
||||
let url = null;
|
||||
const hasHostName = resource.spec?.hostnames;
|
||||
const isHttpRoute = resource.kind === "HTTPRoute";
|
||||
|
||||
if (isHttpRoute && hasHostName) {
|
||||
if (resource.spec.rules[0].matches[0].path.type!=="RegularExpression"){
|
||||
const urlHost = resource.spec.hostnames[0];
|
||||
const urlPath = resource.spec.rules[0].matches[0].path.value;
|
||||
const urlSchema = (await getSchemaFromGateway(resource.spec.parentRefs[0])) ? "https" : "http";
|
||||
url = `${urlSchema}://${urlHost}${urlPath}`;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function getUrlFromIngress(resource) {
|
||||
const isNotHttpRoute = resource.kind !== "HTTPRoute";
|
||||
let url = null
|
||||
|
||||
if (isNotHttpRoute){
|
||||
const urlHost = resource.spec.rules[0].host;
|
||||
const urlPath = resource.spec.rules[0].http.paths[0].path;
|
||||
const urlSchema = resource.spec.tls ? "https" : "http";
|
||||
url = `${urlSchema}://${urlHost}${urlPath}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// async function getHttpRouteList() {
|
||||
|
||||
// const crd = kc.makeApiClient(CustomObjectsApi);
|
||||
// const core = kc.makeApiClient(CoreV1Api);
|
||||
|
||||
// // httproutes
|
||||
// const getHttpRoute = async (namespace) =>
|
||||
// crd
|
||||
// .listNamespacedCustomObject(apiGroup, version, namespace, "httproutes")
|
||||
// .then((response) => {
|
||||
// const [httpRoute] = response.body.items;
|
||||
// return httpRoute;
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// logger.error("Error getting httproutes: %d %s %s", error.statusCode, error.body, error.response);
|
||||
// logger.debug(error);
|
||||
// return null;
|
||||
// });
|
||||
|
||||
// // namespaces
|
||||
// const namespaces = await core
|
||||
// .listNamespace()
|
||||
// .then((response) => response.body.items.map((ns) => ns.metadata.name))
|
||||
// .catch((error) => {
|
||||
// logger.error("Error getting namespaces: %d %s %s", error.statusCode, error.body, error.response);
|
||||
// logger.debug(error);
|
||||
// return null;
|
||||
// });
|
||||
|
||||
// let httpRouteList = [];
|
||||
// if (namespaces) {
|
||||
// const httpRouteListUnfiltered = await Promise.all(
|
||||
// namespaces.map(async (namespace) => {
|
||||
// const httpRoute = await getHttpRoute(namespace);
|
||||
// return httpRoute;
|
||||
// }),
|
||||
// );
|
||||
|
||||
// httpRouteList = httpRouteListUnfiltered.filter((httpRoute) => httpRoute !== undefined);
|
||||
// }
|
||||
// return httpRouteList;
|
||||
// }
|
||||
|
||||
// async function getIngressList(annotationBase) {
|
||||
|
||||
// const { traefik } = kubeArguments;
|
||||
// const networking = kc.makeApiClient(NetworkingV1Api);
|
||||
|
||||
// const ingressList = await networking
|
||||
// .listIngressForAllNamespaces(null, null, null, null)
|
||||
// .then((response) => response.body)
|
||||
// .catch((error) => {
|
||||
// logger.error("Error getting ingresses: %d %s %s", error.statusCode, error.body, error.response);
|
||||
// logger.debug(error);
|
||||
// return null;
|
||||
// });
|
||||
|
||||
// if (traefik) {
|
||||
// const crd = kc.makeApiClient(CustomObjectsApi);
|
||||
// const traefikContainoExists = await checkCRD("ingressroutes.traefik.containo.us",kc,logger);
|
||||
// const traefikExists = await checkCRD("ingressroutes.traefik.io",kc,logger);
|
||||
|
||||
// const traefikIngressListContaino = await crd
|
||||
// .listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
|
||||
// .then((response) => response.body)
|
||||
// .catch(async (error) => {
|
||||
// if (traefikContainoExists) {
|
||||
// logger.error(
|
||||
// "Error getting traefik ingresses from traefik.containo.us: %d %s %s",
|
||||
// error.statusCode,
|
||||
// error.body,
|
||||
// error.response,
|
||||
// );
|
||||
// logger.debug(error);
|
||||
// }
|
||||
|
||||
// return [];
|
||||
// });
|
||||
|
||||
// const traefikIngressListIo = await crd
|
||||
// .listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
|
||||
// .then((response) => response.body)
|
||||
// .catch(async (error) => {
|
||||
// if (traefikExists) {
|
||||
// logger.error(
|
||||
// "Error getting traefik ingresses from traefik.io: %d %s %s",
|
||||
// error.statusCode,
|
||||
// error.body,
|
||||
// error.response,
|
||||
// );
|
||||
// logger.debug(error);
|
||||
// }
|
||||
|
||||
// return [];
|
||||
// });
|
||||
|
||||
// const traefikIngressList = [...(traefikIngressListContaino?.items ?? []), ...(traefikIngressListIo?.items ?? [])];
|
||||
|
||||
// if (traefikIngressList.length > 0) {
|
||||
// const traefikServices = traefikIngressList.filter(
|
||||
// (ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${annotationBase}/href`],
|
||||
// );
|
||||
// ingressList.items.push(...traefikServices);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return ingressList.items;
|
||||
// }
|
||||
|
||||
// export async function getRouteList(annotationBase) {
|
||||
// let routeList = [];
|
||||
|
||||
// if (!kc) {
|
||||
// return [];
|
||||
// }
|
||||
|
||||
// if (kubeArguments.ingress){
|
||||
// routeList = await getIngressList(annotationBase);
|
||||
// }else if (kubeArguments.gateway) {
|
||||
// routeList = await getHttpRouteList();
|
||||
// }else{
|
||||
// routeList = await getIngressList(annotationBase);
|
||||
// }
|
||||
|
||||
// // const routingType = kubeArguments.route;
|
||||
|
||||
// // switch (routingType) {
|
||||
// // case "ingress":
|
||||
// // routeList = await getIngressList(annotationBase);
|
||||
// // break;
|
||||
// // case "gateway":
|
||||
// // routeList = await getHttpRouteList();
|
||||
// // break;
|
||||
// // default:
|
||||
// // routeList = await getIngressList(annotationBase);
|
||||
// // }
|
||||
|
||||
// return routeList;
|
||||
// }
|
||||
|
||||
export default async function getUrlSchema(resource) {
|
||||
let urlSchema;
|
||||
|
||||
if (kubeArguments.ingress){
|
||||
urlSchema = getUrlFromIngress(resource);
|
||||
}else if (kubeArguments.gateway){
|
||||
urlSchema = await getUrlFromHttpRoute(resource);
|
||||
}else{
|
||||
urlSchema = getUrlFromIngress(resource);
|
||||
}
|
||||
|
||||
// const routingType = kubeArguments.route;
|
||||
// switch (routingType) {
|
||||
// case "ingress":
|
||||
// urlSchema = getUrlFromIngress(route);
|
||||
// break;
|
||||
// case "gateway":
|
||||
// urlSchema = await getUrlFromHttpRoute(route);
|
||||
// break;
|
||||
// default:
|
||||
// urlSchema = getUrlFromIngress(route);
|
||||
// }
|
||||
return urlSchema;
|
||||
}
|
||||
@@ -1,10 +1,72 @@
|
||||
import getUrlSchema from "utils/kubernetes/kubernetes-routes";
|
||||
import { CustomObjectsApi } from "@kubernetes/client-node";
|
||||
|
||||
import getKubeArguments,{ ANNOTATION_BASE,ANNOTATION_WIDGET_BASE,HTTPROUTE_API_GROUP,HTTPROUTE_API_VERSION } from "utils/config/kubernetes";
|
||||
import { substituteEnvironmentVars } from "utils/config/config";
|
||||
import { ANNOTATION_BASE,ANNOTATION_WIDGET_BASE } from "utils/config/kubernetes";
|
||||
import createLogger from "utils/logger";
|
||||
import * as shvl from "utils/config/shvl";
|
||||
|
||||
const logger = createLogger("resource-helpers");
|
||||
const kubeArguments = getKubeArguments();
|
||||
const kc = kubeArguments.config;
|
||||
|
||||
const getSchemaFromGateway = async (gatewayRef) => {
|
||||
const crd = kc.makeApiClient(CustomObjectsApi);
|
||||
const schema = await crd
|
||||
.getNamespacedCustomObject(HTTPROUTE_API_GROUP, HTTPROUTE_API_VERSION, gatewayRef.namespace, "gateways", gatewayRef.name)
|
||||
.then((response) => {
|
||||
const listner = response.body.spec.listeners.filter((listener) => listener.name === gatewayRef.sectionName)[0];
|
||||
return listner.protocol.toLowerCase();
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error("Error getting gateways: %d %s %s", error.statusCode, error.body, error.response);
|
||||
logger.debug(error);
|
||||
return "";
|
||||
});
|
||||
return schema;
|
||||
};
|
||||
|
||||
async function getUrlFromHttpRoute(resource) {
|
||||
let url = null;
|
||||
const hasHostName = resource.spec?.hostnames;
|
||||
const isHttpRoute = resource.kind === "HTTPRoute";
|
||||
|
||||
if (isHttpRoute && hasHostName) {
|
||||
if (resource.spec.rules[0].matches[0].path.type!=="RegularExpression"){
|
||||
const urlHost = resource.spec.hostnames[0];
|
||||
const urlPath = resource.spec.rules[0].matches[0].path.value;
|
||||
const urlSchema = (await getSchemaFromGateway(resource.spec.parentRefs[0])) ? "https" : "http";
|
||||
url = `${urlSchema}://${urlHost}${urlPath}`;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function getUrlFromIngress(resource) {
|
||||
const isNotHttpRoute = resource.kind !== "HTTPRoute";
|
||||
let url = null
|
||||
|
||||
if (isNotHttpRoute){
|
||||
const urlHost = resource.spec.rules[0].host;
|
||||
const urlPath = resource.spec.rules[0].http.paths[0].path;
|
||||
const urlSchema = resource.spec.tls ? "https" : "http";
|
||||
url = `${urlSchema}://${urlHost}${urlPath}`;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
async function getUrlSchema(resource) {
|
||||
let urlSchema;
|
||||
|
||||
if (kubeArguments.ingress){
|
||||
urlSchema = getUrlFromIngress(resource);
|
||||
}else if (kubeArguments.gateway){
|
||||
urlSchema = await getUrlFromHttpRoute(resource);
|
||||
}else{
|
||||
urlSchema = getUrlFromIngress(resource);
|
||||
}
|
||||
|
||||
return urlSchema;
|
||||
}
|
||||
|
||||
export function isDiscoverable(resource,instanceName) {
|
||||
return resource.metadata.annotations &&
|
||||
|
||||
Reference in New Issue
Block a user