import { Service } from 'kubernetes-types/core/v1';
import { useMemo } from 'react';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { useIngresses } from '@/react/kubernetes/ingresses/queries';
import { Ingress } from '@/react/kubernetes/ingresses/types';
import { Authorized } from '@/react/hooks/useUser';
import { Link } from '@@/Link';
type Props = {
environmentId: EnvironmentId;
namespace: string;
appServices?: Service[];
};
export function ApplicationIngressesTable({
environmentId,
namespace,
appServices,
}: Props) {
const namespaceIngresses = useIngresses(environmentId, [namespace]);
// getIngressPathsForAppServices could be expensive, so memoize it
const ingressPathsForAppServices = useMemo(
() => getIngressPathsForAppServices(namespaceIngresses.data, appServices),
[namespaceIngresses.data, appServices]
);
if (!ingressPathsForAppServices.length) {
return null;
}
return (
Ingress name |
Service name |
Host |
Port |
Path |
HTTP Route |
{ingressPathsForAppServices.map((ingressPath, index) => (
{ingressPath.ingressName}
|
{ingressPath.serviceName} |
{ingressPath.host} |
{ingressPath.port} |
{ingressPath.path} |
{ingressPath.host}
{ingressPath.path}
|
))}
);
}
type IngressPath = {
ingressName: string;
serviceName: string;
port: number;
secure: boolean;
host: string;
path: string;
};
function getIngressPathsForAppServices(
ingresses?: Ingress[],
services?: Service[]
): IngressPath[] {
if (!ingresses || !services) {
return [];
}
const matchingIngressesPaths = ingresses.flatMap((ingress) => {
// for each ingress get an array of ingress paths that match the app services
const matchingIngressPaths = ingress.Paths.filter((path) =>
services?.some((service) => {
const servicePorts = service.spec?.ports?.map((port) => port.port);
// include the ingress if the ingress path has a matching service name and port
return (
path.ServiceName === service.metadata?.name &&
servicePorts?.includes(path.Port)
);
})
).map((path) => {
const secure =
(ingress.TLS &&
ingress.TLS.filter(
(tls) => tls.Hosts && tls.Hosts.includes(path.Host)
).length > 0) ??
false;
return {
ingressName: ingress.Name,
serviceName: path.ServiceName,
port: path.Port,
secure,
host: path.Host,
path: path.Path,
};
});
return matchingIngressPaths;
});
return matchingIngressesPaths;
}