diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index 07677e99c..82b1162b2 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -191,32 +191,33 @@ export async function servicesFromKubernetes() { if (!resources) { return []; } - - const services = resources + const services = await Promise.all( resources .filter(resource => kubernetes.isDiscoverable(resource, instanceName)) - .map(resource => kubernetes.constructedServiceFromResource(resource)); + .map(async (resource) => kubernetes.constructedServiceFromResource(resource))); - // const mappedServiceGroups = services.reduce((groups, serverService) => { - // let serverGroup = groups.find(group => group.name === serverService.group); + const mappedServiceGroups = services.reduce((groups, serverService) => { + let serverGroup = groups.find(group => group.name === serverService.group); - // if (!serverGroup) { - // serverGroup = { - // name: serverService.group, - // services: [] - // }; - // groups.push(serverGroup); - // } + if (!serverGroup) { + serverGroup = { + name: serverService.group, + services: [] + }; + groups.push(serverGroup); + } - // const { name: serviceName, group: _, ...pushedService } = serverService; + const { name: serviceName, group: _, ...pushedService } = serverService; - // serverGroup.services.push({ - // name: serviceName, - // ...pushedService - // }); + serverGroup.services.push({ + name: serviceName, + ...pushedService + }); - // return groups; - // }, []); + return groups; + }, []); + + // console.log(mappedServiceGroups); // const routeList = await getRouteList(ANNOTATION_BASE); // if (!routeList) { @@ -282,26 +283,26 @@ export async function servicesFromKubernetes() { // }), // ); - const mappedServiceGroups = []; + // 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]; - } + // 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, - }; + // const { name: serviceName, group: serverServiceGroup, ...pushedService } = serverService; + // const result = { + // name: serviceName, + // ...pushedService, + // }; - serverGroup.services.push(result); - }); + // serverGroup.services.push(result); + // }); return mappedServiceGroups; } catch (e) { diff --git a/src/utils/kubernetes/kubernetes-routes.js b/src/utils/kubernetes/kubernetes-routes.js index ff283368d..875956eed 100644 --- a/src/utils/kubernetes/kubernetes-routes.js +++ b/src/utils/kubernetes/kubernetes-routes.js @@ -1,6 +1,6 @@ -import { CustomObjectsApi, NetworkingV1Api, CoreV1Api } from "@kubernetes/client-node"; +import { CustomObjectsApi } from "@kubernetes/client-node"; -import getKubeArguments,{checkCRD} from "utils/config/kubernetes"; +import getKubeArguments from "utils/config/kubernetes"; import createLogger from "utils/logger"; const logger = createLogger("service-helpers"); @@ -27,172 +27,196 @@ const getSchemaFromGateway = async (gatewayRef) => { return schema; }; -async function getUrlFromHttpRoute(ingress) { - - let url = null - if (ingress.spec.has("hostnames")) { - if (ingress.spec.rules[0].matches[0].path.type!=="RegularExpression"){ - const urlHost = ingress.spec.hostnames[0]; - const urlPath = ingress.spec.rules[0].matches[0].path.value; - const urlSchema = (await getSchemaFromGateway(ingress.spec.parentRefs[0])) ? "https" : "http"; +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(ingress) { - const urlHost = ingress.spec.rules[0].host; - const urlPath = ingress.spec.rules[0].http.paths[0].path; - const urlSchema = ingress.spec.tls ? "https" : "http"; - return `${urlSchema}://${urlHost}${urlPath}`; -}; +function getUrlFromIngress(resource) { + const isNotHttpRoute = resource.kind !== "HTTPRoute"; + let url = null -async function getHttpRouteList() { + 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); +// 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; - }); +// // 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; - }); +// // 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; - }), - ); +// 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; -}; +// httpRouteList = httpRouteListUnfiltered.filter((httpRoute) => httpRoute !== undefined); +// } +// return httpRouteList; +// } -async function getIngressList(annotationBase) { +// async function getIngressList(annotationBase) { - const {traefik} = kubeArguments; - const networking = kc.makeApiClient(NetworkingV1Api); +// 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; - }); +// 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); +// 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); - } +// 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 []; - }); +// 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); - } +// 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 []; - }); +// return []; +// }); - const traefikIngressList = [...(traefikIngressListContaino?.items ?? []), ...(traefikIngressListIo?.items ?? [])]; +// 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); - } - } +// if (traefikIngressList.length > 0) { +// const traefikServices = traefikIngressList.filter( +// (ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${annotationBase}/href`], +// ); +// ingressList.items.push(...traefikServices); +// } +// } - return ingressList.items; -}; +// return ingressList.items; +// } -export async function getRouteList(annotationBase) { - let routeList = []; +// export async function getRouteList(annotationBase) { +// let routeList = []; - if (!kc) { - return []; - } +// if (!kc) { +// return []; +// } - const routingType = kubeArguments.route; +// if (kubeArguments.ingress){ +// routeList = await getIngressList(annotationBase); +// }else if (kubeArguments.gateway) { +// routeList = await getHttpRouteList(); +// }else{ +// routeList = await getIngressList(annotationBase); +// } - switch (routingType) { - case "ingress": - routeList = await getIngressList(annotationBase); - break; - case "gateway": - routeList = await getHttpRouteList(); - break; - default: - routeList = await getIngressList(annotationBase); - } +// // const routingType = kubeArguments.route; - return routeList; -}; +// // switch (routingType) { +// // case "ingress": +// // routeList = await getIngressList(annotationBase); +// // break; +// // case "gateway": +// // routeList = await getHttpRouteList(); +// // break; +// // default: +// // routeList = await getIngressList(annotationBase); +// // } -export async function getUrlSchema(route) { +// return routeList; +// } + +export default async function getUrlSchema(resource) { let urlSchema; - const routingType = kubeArguments.route; - switch (routingType) { - case "ingress": - urlSchema = getUrlFromIngress(route); - break; - case "gateway": - urlSchema = await getUrlFromHttpRoute(route); - break; - default: - urlSchema = getUrlFromIngress(route); + 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; -}; +} diff --git a/src/utils/kubernetes/resource-helpers.js b/src/utils/kubernetes/resource-helpers.js index 95c97c1c3..565393b10 100644 --- a/src/utils/kubernetes/resource-helpers.js +++ b/src/utils/kubernetes/resource-helpers.js @@ -1,49 +1,47 @@ import getUrlSchema from "utils/kubernetes/kubernetes-routes"; 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"); -export function isDiscoverable(resource,instanceName,annotationBase) { +export function isDiscoverable(resource,instanceName) { return resource.metadata.annotations && - resource.metadata.annotations[`${annotationBase}/enabled`] === "true" && - (!resource.metadata.annotations[`${annotationBase}/instance`] || - resource.metadata.annotations[`${annotationBase}/instance`] === instanceName || - `${annotationBase}/instance.${instanceName}` in resource.metadata.annotations) -} - -export async function constructedServiceFromResource (resource,annotationBase){ - - const ANNOTATION_WIDGET_BASE = `${annotationBase}/widget.`; + resource.metadata.annotations[`${ANNOTATION_BASE}/enabled`] === "true" && + (!resource.metadata.annotations[`${ANNOTATION_BASE}/instance`] || + resource.metadata.annotations[`${ANNOTATION_BASE}/instance`] === instanceName || + `${ANNOTATION_BASE}/instance.${instanceName}` in resource.metadata.annotations) +}; +export async function constructedServiceFromResource (resource){ let constructedService = { - app: resource.metadata.annotations[`${annotationBase}/app`] || resource.metadata.name, + app: resource.metadata.annotations[`${ANNOTATION_BASE}/app`] || resource.metadata.name, namespace: resource.metadata.namespace, - href: resource.metadata.annotations[`${annotationBase}/href`] || (await getUrlSchema(resource)), - name: resource.metadata.annotations[`${annotationBase}/name`] || resource.metadata.name, - group: resource.metadata.annotations[`${annotationBase}/group`] || "Kubernetes", - weight: resource.metadata.annotations[`${annotationBase}/weight`] || "0", - icon: resource.metadata.annotations[`${annotationBase}/icon`] || "", - description: resource.metadata.annotations[`${annotationBase}/description`] || "", + href: resource.metadata.annotations[`${ANNOTATION_BASE}/href`] || (await getUrlSchema(resource)), + name: resource.metadata.annotations[`${ANNOTATION_BASE}/name`] || resource.metadata.name, + group: resource.metadata.annotations[`${ANNOTATION_BASE}/group`] || "Kubernetes", + weight: resource.metadata.annotations[`${ANNOTATION_BASE}/weight`] || "0", + icon: resource.metadata.annotations[`${ANNOTATION_BASE}/icon`] || "", + description: resource.metadata.annotations[`${ANNOTATION_BASE}/description`] || "", external: false, type: "service", }; - if (resource.metadata.annotations[`${annotationBase}/external`]) { + if (resource.metadata.annotations[`${ANNOTATION_BASE}/external`]) { constructedService.external = - String(resource.metadata.annotations[`${annotationBase}/external`]).toLowerCase() === "true"; + String(resource.metadata.annotations[`${ANNOTATION_BASE}/external`]).toLowerCase() === "true"; } - if (resource.metadata.annotations[`${annotationBase}/pod-selector`] !== undefined) { - constructedService.podSelector = resource.metadata.annotations[`${annotationBase}/pod-selector`]; + if (resource.metadata.annotations[`${ANNOTATION_BASE}/pod-selector`] !== undefined) { + constructedService.podSelector = resource.metadata.annotations[`${ANNOTATION_BASE}/pod-selector`]; } - if (resource.metadata.annotations[`${annotationBase}/ping`]) { - constructedService.ping = resource.metadata.annotations[`${annotationBase}/ping`]; + if (resource.metadata.annotations[`${ANNOTATION_BASE}/ping`]) { + constructedService.ping = resource.metadata.annotations[`${ANNOTATION_BASE}/ping`]; } - if (resource.metadata.annotations[`${annotationBase}/siteMonitor`]) { - constructedService.siteMonitor = resource.metadata.annotations[`${annotationBase}/siteMonitor`]; + if (resource.metadata.annotations[`${ANNOTATION_BASE}/siteMonitor`]) { + constructedService.siteMonitor = resource.metadata.annotations[`${ANNOTATION_BASE}/siteMonitor`]; } - if (resource.metadata.annotations[`${annotationBase}/statusStyle`]) { - constructedService.statusStyle = resource.metadata.annotations[`${annotationBase}/statusStyle`]; + if (resource.metadata.annotations[`${ANNOTATION_BASE}/statusStyle`]) { + constructedService.statusStyle = resource.metadata.annotations[`${ANNOTATION_BASE}/statusStyle`]; } Object @@ -52,7 +50,7 @@ export async function constructedServiceFromResource (resource,annotationBase){ if (annotation.startsWith(ANNOTATION_WIDGET_BASE)) { shvl.set( constructedService, - annotation.replace(`${annotationBase}/`, ""), + annotation.replace(`${ANNOTATION_BASE}/`, ""), resource.metadata.annotations[annotation], ); }