From d8a50bc0ec93e992c7f4e7f11c27e0d0cc5343bd Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 5 Jan 2022 10:08:35 -0500 Subject: [PATCH] Add links for ingresses Signed-off-by: Sebastian Malton --- src/common/k8s-api/endpoints/ingress.api.ts | 72 +++++++++--------- .../+network-ingresses/ingress-details.tsx | 76 ++++++++++--------- .../+network-ingresses/ingresses.tsx | 12 ++- 3 files changed, 89 insertions(+), 71 deletions(-) diff --git a/src/common/k8s-api/endpoints/ingress.api.ts b/src/common/k8s-api/endpoints/ingress.api.ts index b5feaef2c0..254f68a411 100644 --- a/src/common/k8s-api/endpoints/ingress.api.ts +++ b/src/common/k8s-api/endpoints/ingress.api.ts @@ -4,7 +4,7 @@ */ import { KubeObject } from "../kube-object"; -import { autoBind } from "../../utils"; +import { autoBind, iter } from "../../utils"; import { IMetrics, metricsApi } from "./metrics.api"; import { KubeApi } from "../kube-api"; import type { KubeJsonApiData } from "../kube-json-api"; @@ -61,23 +61,30 @@ export interface IIngressService { }; } -export const getBackendServiceNamePort = (backend: IIngressBackend) => { +/** + * Format an ingress backend into the name of the service and port + * @param backend The ingress target + */ +export function getBackendServiceNamePort(backend: IIngressBackend): string { // .service is available with networking.k8s.io/v1, otherwise using extensions/v1beta1 interface - const serviceName = "service" in backend ? backend.service.name : backend.serviceName; - // Port is specified either with a number or name - const servicePort = "service" in backend ? backend.service.port.number ?? backend.service.port.name : backend.servicePort; - return { serviceName, servicePort }; -}; + if ("service" in backend) { + const { name, port } = backend.service; + + return `${name}:${port.number ?? port.name}`; + } + + return `${backend.serviceName}:${backend.servicePort}`; +} export interface Ingress { spec: { - tls: { + tls?: { secretName: string; }[]; rules?: { host?: string; - http: { + http?: { paths: { path?: string; backend: IIngressBackend; @@ -106,6 +113,11 @@ export interface Ingress { }; } +export interface ComputedIngressRoute { + url: string; + service: string; +} + export class Ingress extends KubeObject { static kind = "Ingress"; static namespaced = true; @@ -116,30 +128,22 @@ export class Ingress extends KubeObject { autoBind(this); } - getRoutes() { - const { spec: { tls, rules }} = this; + getRoutes(): string[] { + return this.getRouteDecls().map(({ url, service }) => `${url} ⇢ ${service}`); + } - if (!rules) return []; + getRouteDecls(): ComputedIngressRoute[] { + const { spec: { tls = [], rules = [] }} = this; + const protocol = tls.length === 0 + ? "http" + : "https"; - let protocol = "http"; - const routes: string[] = []; - - if (tls && tls.length > 0) { - protocol += "s"; - } - rules.map(rule => { - const host = rule.host ? rule.host : "*"; - - if (rule.http && rule.http.paths) { - rule.http.paths.forEach(path => { - const { serviceName, servicePort } = getBackendServiceNamePort(path.backend); - - routes.push(`${protocol}://${host}${path.path || "/"} ⇢ ${serviceName}:${servicePort}`); - }); - } - }); - - return routes; + return rules.flatMap(({ host = "*", http: { paths } = { paths: [] }}) => ( + paths.map(({ path = "/", backend }) => ({ + url: `${protocol}://${host}${path}`, + service: getBackendServiceNamePort(backend), + })) + )); } getServiceNamePort(): IExtensionsBackend { @@ -155,11 +159,9 @@ export class Ingress extends KubeObject { } getHosts() { - const { spec: { rules }} = this; + const { spec: { rules = [] }} = this; - if (!rules) return []; - - return rules.filter(rule => rule.host).map(rule => rule.host); + return [...iter.filterMap(rules, rule => rule.host)]; } getPorts() { diff --git a/src/renderer/components/+network-ingresses/ingress-details.tsx b/src/renderer/components/+network-ingresses/ingress-details.tsx index 5254b2c663..a220e21290 100644 --- a/src/renderer/components/+network-ingresses/ingress-details.tsx +++ b/src/renderer/components/+network-ingresses/ingress-details.tsx @@ -49,44 +49,51 @@ export class IngressDetails extends React.Component { } renderPaths(ingress: Ingress) { - const { spec: { rules }} = ingress; + const { spec: { rules = [], tls = [] }} = ingress; + const protocol = tls.length === 0 + ? "http" + : "https"; - if (!rules || !rules.length) return null; - - return rules.map((rule, index) => { - return ( -
- {rule.host && ( -
- <>Host: {rule.host} -
- )} - {rule.http && ( - - - Path - Backends - - { - rule.http.paths.map((path, index) => { - const { serviceName, servicePort } = getBackendServiceNamePort(path.backend); - const backend = `${serviceName}:${servicePort}`; + return rules.map((rule, index) => ( +
+ {rule.host && ( +
+ <>Host: {rule.host} +
+ )} + {rule.http && ( +
+ + Path + Link + Backends + + { + rule.http.paths + .map(({ path = "/", backend }, index) => { + const link = `${protocol}://${rule.host || "*"}${path}`; return ( - {path.path || ""} - -

{backend}

+ {path} + + + {link} + + {getBackendServiceNamePort(backend)}
); }) - } -
- )} -
- ); - }); + } + + )} + + )); } renderIngressPoints(ingressPoints: ILoadBalancerIngress[]) { @@ -99,15 +106,14 @@ export class IngressDetails extends React.Component { Hostname IP - {ingressPoints.map(({ hostname, ip }, index) => { - return ( + { + ingressPoints.map(({ hostname, ip }, index) => ( {hostname ? hostname : "-"} {ip ? ip : "-"} - ); - }) - }) + )) + } ); diff --git a/src/renderer/components/+network-ingresses/ingresses.tsx b/src/renderer/components/+network-ingresses/ingresses.tsx index d86fb98079..20d1340a9f 100644 --- a/src/renderer/components/+network-ingresses/ingresses.tsx +++ b/src/renderer/components/+network-ingresses/ingresses.tsx @@ -56,7 +56,17 @@ export class Ingresses extends React.Component { , ingress.getNs(), ingress.getLoadBalancers().map(lb =>

{lb}

), - ingress.getRoutes().map(route =>

{route}

), + ingress.getRouteDecls().map(route => ( + e.stopPropagation()} + > + {route.url} + + )), , ]} tableProps={{