mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add links for ingresses
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
a76fc6df84
commit
d8a50bc0ec
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { KubeObject } from "../kube-object";
|
import { KubeObject } from "../kube-object";
|
||||||
import { autoBind } from "../../utils";
|
import { autoBind, iter } from "../../utils";
|
||||||
import { IMetrics, metricsApi } from "./metrics.api";
|
import { IMetrics, metricsApi } from "./metrics.api";
|
||||||
import { KubeApi } from "../kube-api";
|
import { KubeApi } from "../kube-api";
|
||||||
import type { KubeJsonApiData } from "../kube-json-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
|
// .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 {
|
export interface Ingress {
|
||||||
spec: {
|
spec: {
|
||||||
tls: {
|
tls?: {
|
||||||
secretName: string;
|
secretName: string;
|
||||||
}[];
|
}[];
|
||||||
rules?: {
|
rules?: {
|
||||||
host?: string;
|
host?: string;
|
||||||
http: {
|
http?: {
|
||||||
paths: {
|
paths: {
|
||||||
path?: string;
|
path?: string;
|
||||||
backend: IIngressBackend;
|
backend: IIngressBackend;
|
||||||
@ -106,6 +113,11 @@ export interface Ingress {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ComputedIngressRoute {
|
||||||
|
url: string;
|
||||||
|
service: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class Ingress extends KubeObject {
|
export class Ingress extends KubeObject {
|
||||||
static kind = "Ingress";
|
static kind = "Ingress";
|
||||||
static namespaced = true;
|
static namespaced = true;
|
||||||
@ -116,30 +128,22 @@ export class Ingress extends KubeObject {
|
|||||||
autoBind(this);
|
autoBind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRoutes() {
|
getRoutes(): string[] {
|
||||||
const { spec: { tls, rules }} = this;
|
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";
|
return rules.flatMap(({ host = "*", http: { paths } = { paths: [] }}) => (
|
||||||
const routes: string[] = [];
|
paths.map(({ path = "/", backend }) => ({
|
||||||
|
url: `${protocol}://${host}${path}`,
|
||||||
if (tls && tls.length > 0) {
|
service: getBackendServiceNamePort(backend),
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getServiceNamePort(): IExtensionsBackend {
|
getServiceNamePort(): IExtensionsBackend {
|
||||||
@ -155,11 +159,9 @@ export class Ingress extends KubeObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getHosts() {
|
getHosts() {
|
||||||
const { spec: { rules }} = this;
|
const { spec: { rules = [] }} = this;
|
||||||
|
|
||||||
if (!rules) return [];
|
return [...iter.filterMap(rules, rule => rule.host)];
|
||||||
|
|
||||||
return rules.filter(rule => rule.host).map(rule => rule.host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getPorts() {
|
getPorts() {
|
||||||
|
|||||||
@ -49,44 +49,51 @@ export class IngressDetails extends React.Component<IngressDetailsProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderPaths(ingress: Ingress) {
|
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) => (
|
||||||
|
<div className="rules" key={index}>
|
||||||
return rules.map((rule, index) => {
|
{rule.host && (
|
||||||
return (
|
<div className="host-title">
|
||||||
<div className="rules" key={index}>
|
<>Host: {rule.host}</>
|
||||||
{rule.host && (
|
</div>
|
||||||
<div className="host-title">
|
)}
|
||||||
<>Host: {rule.host}</>
|
{rule.http && (
|
||||||
</div>
|
<Table className="paths">
|
||||||
)}
|
<TableHead>
|
||||||
{rule.http && (
|
<TableCell className="path">Path</TableCell>
|
||||||
<Table className="paths">
|
<TableCell className="link">Link</TableCell>
|
||||||
<TableHead>
|
<TableCell className="backends">Backends</TableCell>
|
||||||
<TableCell className="path">Path</TableCell>
|
</TableHead>
|
||||||
<TableCell className="backends">Backends</TableCell>
|
{
|
||||||
</TableHead>
|
rule.http.paths
|
||||||
{
|
.map(({ path = "/", backend }, index) => {
|
||||||
rule.http.paths.map((path, index) => {
|
const link = `${protocol}://${rule.host || "*"}${path}`;
|
||||||
const { serviceName, servicePort } = getBackendServiceNamePort(path.backend);
|
|
||||||
const backend = `${serviceName}:${servicePort}`;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell className="path">{path.path || ""}</TableCell>
|
<TableCell className="path">{path}</TableCell>
|
||||||
<TableCell className="backends">
|
<TableCell className="link">
|
||||||
<p key={backend}>{backend}</p>
|
<a
|
||||||
|
href={link}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
{link}
|
||||||
|
</a>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className="backends">{getBackendServiceNamePort(backend)}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderIngressPoints(ingressPoints: ILoadBalancerIngress[]) {
|
renderIngressPoints(ingressPoints: ILoadBalancerIngress[]) {
|
||||||
@ -99,15 +106,14 @@ export class IngressDetails extends React.Component<IngressDetailsProps> {
|
|||||||
<TableCell className="name">Hostname</TableCell>
|
<TableCell className="name">Hostname</TableCell>
|
||||||
<TableCell className="ingresspoints">IP</TableCell>
|
<TableCell className="ingresspoints">IP</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ingressPoints.map(({ hostname, ip }, index) => {
|
{
|
||||||
return (
|
ingressPoints.map(({ hostname, ip }, index) => (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell className="name">{hostname ? hostname : "-"}</TableCell>
|
<TableCell className="name">{hostname ? hostname : "-"}</TableCell>
|
||||||
<TableCell className="ingresspoints">{ip ? ip : "-"}</TableCell>
|
<TableCell className="ingresspoints">{ip ? ip : "-"}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
))
|
||||||
})
|
}
|
||||||
})
|
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -56,7 +56,17 @@ export class Ingresses extends React.Component<IngressesProps> {
|
|||||||
<KubeObjectStatusIcon key="icon" object={ingress} />,
|
<KubeObjectStatusIcon key="icon" object={ingress} />,
|
||||||
ingress.getNs(),
|
ingress.getNs(),
|
||||||
ingress.getLoadBalancers().map(lb => <p key={lb}>{lb}</p>),
|
ingress.getLoadBalancers().map(lb => <p key={lb}>{lb}</p>),
|
||||||
ingress.getRoutes().map(route => <p key={route}>{route}</p>),
|
ingress.getRouteDecls().map(route => (
|
||||||
|
<a
|
||||||
|
key={route.url}
|
||||||
|
href={route.url}
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{route.url}
|
||||||
|
</a>
|
||||||
|
)),
|
||||||
<KubeObjectAge key="age" object={ingress} />,
|
<KubeObjectAge key="age" object={ingress} />,
|
||||||
]}
|
]}
|
||||||
tableProps={{
|
tableProps={{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user