From 4c9d60d76d87ca618aa2209cce0a75de286213f0 Mon Sep 17 00:00:00 2001 From: Jim Ehrismann Date: Thu, 23 Dec 2021 14:43:17 -0500 Subject: [PATCH] documentation, more cleanup Signed-off-by: Jim Ehrismann --- src/main/router.ts | 1 - src/main/routes/port-forward-route.ts | 25 ------ .../service-port-component.tsx | 4 +- .../+workloads-pods/pod-container-port.tsx | 5 +- .../port-forward/port-forward-dialog.tsx | 10 +-- .../port-forward/port-forward-notify.tsx | 31 +++++++ .../port-forward/port-forward.store.ts | 81 ++++++++++++++----- 7 files changed, 100 insertions(+), 57 deletions(-) diff --git a/src/main/router.ts b/src/main/router.ts index 96ed7cdd02..082d710f68 100644 --- a/src/main/router.ts +++ b/src/main/router.ts @@ -182,7 +182,6 @@ export class Router { // Port-forward API (the container port and local forwarding port are obtained from the query parameters) this.router.add({ method: "post", path: `${apiPrefix}/pods/port-forward/{namespace}/{resourceType}/{resourceName}` }, PortForwardRoute.routePortForward); this.router.add({ method: "get", path: `${apiPrefix}/pods/port-forward/{namespace}/{resourceType}/{resourceName}` }, PortForwardRoute.routeCurrentPortForward); - this.router.add({ method: "get", path: `${apiPrefix}/pods/port-forwards` }, PortForwardRoute.routeAllPortForwards); this.router.add({ method: "delete", path: `${apiPrefix}/pods/port-forward/{namespace}/{resourceType}/{resourceName}` }, PortForwardRoute.routeCurrentPortForwardStop); // Helm API diff --git a/src/main/routes/port-forward-route.ts b/src/main/routes/port-forward-route.ts index 6392c70ed9..030ec8ff07 100644 --- a/src/main/routes/port-forward-route.ts +++ b/src/main/routes/port-forward-route.ts @@ -188,31 +188,6 @@ export class PortForwardRoute { respondJson(response, { port: portForward?.forwardPort ?? null }); } - static async routeAllPortForwards(request: LensApiRequest) { - const { query, response } = request; - const clusterId = query.get("clusterId"); - - let portForwards: PortForwardArgs[] = PortForward.portForwards.map(f => ( - { - clusterId: f.clusterId, - kind: f.kind, - namespace: f.namespace, - name: f.name, - port: f.port, - forwardPort: f.forwardPort, - protocol: f.protocol, - }), - ); - - if (clusterId) { - // filter out any not for this cluster - portForwards = portForwards.filter(pf => pf.clusterId == clusterId); - - } - - respondJson(response, { portForwards }); - } - static async routeCurrentPortForwardStop(request: LensApiRequest) { const { params, query, response, cluster } = request; const { namespace, resourceType, resourceName } = params; diff --git a/src/renderer/components/+network-services/service-port-component.tsx b/src/renderer/components/+network-services/service-port-component.tsx index 7a1a3d8be3..796c403cbd 100644 --- a/src/renderer/components/+network-services/service-port-component.tsx +++ b/src/renderer/components/+network-services/service-port-component.tsx @@ -28,7 +28,7 @@ import { observable, makeObservable, reaction, action } from "mobx"; import { cssNames } from "../../utils"; import { Notifications } from "../notifications"; import { Button } from "../button"; -import { aboutPortForwarding, addPortForward, getPortForward, getPortForwards, openPortForward, PortForwardDialog, predictProtocol, removePortForward, startPortForward } from "../../port-forward"; +import { aboutPortForwarding, addPortForward, getPortForward, getPortForwards, notifyErrorPortForwarding, openPortForward, PortForwardDialog, predictProtocol, removePortForward, startPortForward } from "../../port-forward"; import type { ForwardedPort } from "../../port-forward"; import { Spinner } from "../spinner"; import logger from "../../../common/logger"; @@ -117,7 +117,7 @@ export class ServicePortComponent extends React.Component { aboutPortForwarding(); } } else { - Notifications.error(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); + notifyErrorPortForwarding(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); } } catch (error) { logger.error("[SERVICE-PORT-COMPONENT]:", error, portForward); diff --git a/src/renderer/components/+workloads-pods/pod-container-port.tsx b/src/renderer/components/+workloads-pods/pod-container-port.tsx index 1d23300523..768ea50220 100644 --- a/src/renderer/components/+workloads-pods/pod-container-port.tsx +++ b/src/renderer/components/+workloads-pods/pod-container-port.tsx @@ -28,7 +28,8 @@ import { action, observable, makeObservable, reaction } from "mobx"; import { cssNames } from "../../utils"; import { Notifications } from "../notifications"; import { Button } from "../button"; -import { aboutPortForwarding, addPortForward, getPortForward, getPortForwards, openPortForward, PortForwardDialog, predictProtocol, removePortForward, startPortForward } from "../../port-forward";import type { ForwardedPort } from "../../port-forward"; +import { aboutPortForwarding, addPortForward, getPortForward, getPortForwards, notifyErrorPortForwarding, openPortForward, PortForwardDialog, predictProtocol, removePortForward, startPortForward } from "../../port-forward"; +import type { ForwardedPort } from "../../port-forward"; import { Spinner } from "../spinner"; import logger from "../../../common/logger"; @@ -118,7 +119,7 @@ export class PodContainerPort extends React.Component { aboutPortForwarding(); } } else { - Notifications.error(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); + notifyErrorPortForwarding(`Error occurred starting port-forward, the local port may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); } } catch (error) { logger.error("[POD-CONTAINER-PORT]:", error, portForward); diff --git a/src/renderer/port-forward/port-forward-dialog.tsx b/src/renderer/port-forward/port-forward-dialog.tsx index 39a31539ba..d63464880b 100644 --- a/src/renderer/port-forward/port-forward-dialog.tsx +++ b/src/renderer/port-forward/port-forward-dialog.tsx @@ -27,14 +27,12 @@ import { observer } from "mobx-react"; import { Dialog, DialogProps } from "../components/dialog"; import { Wizard, WizardStep } from "../components/wizard"; import { Input } from "../components/input"; -import { Notifications } from "../components/notifications"; -import { cssNames } from "../utils"; +import { cssNames, noop } from "../utils"; import { addPortForward, getPortForwards, modifyPortForward } from "./port-forward.store"; import type { ForwardedPort } from "./port-forward-item"; -import { aboutPortForwarding, openPortForward } from "."; +import { aboutPortForwarding, notifyErrorPortForwarding, openPortForward } from "."; import { Checkbox } from "../components/checkbox"; import logger from "../../common/logger"; -import { noop } from "lodash"; interface Props extends Partial { } @@ -113,14 +111,14 @@ export class PortForwardDialog extends Component { portForward = await modifyPortForward(portForward, desiredPort); if (wasRunning && portForward.status === "Disabled") { - Notifications.error(`Error occurred starting port-forward, the local port ${portForward.forwardPort} may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); + notifyErrorPortForwarding(`Error occurred starting port-forward, the local port ${portForward.forwardPort} may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); } } else { portForward.forwardPort = desiredPort; portForward = await addPortForward(portForward); if (portForward.status === "Disabled") { - Notifications.error(`Error occurred starting port-forward, the local port ${portForward.forwardPort} may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); + notifyErrorPortForwarding(`Error occurred starting port-forward, the local port ${portForward.forwardPort} may not be available or the ${portForward.kind} ${portForward.name} may not be reachable`); } else { // if this is the first port-forward show the about notification if (!length) { diff --git a/src/renderer/port-forward/port-forward-notify.tsx b/src/renderer/port-forward/port-forward-notify.tsx index 4b26fb976c..788a5b672d 100644 --- a/src/renderer/port-forward/port-forward-notify.tsx +++ b/src/renderer/port-forward/port-forward-notify.tsx @@ -56,3 +56,34 @@ export function aboutPortForwarding() { }, ); } + +export function notifyErrorPortForwarding(msg: string) { + const notificationId = `port-forward-error-notification-${getHostedClusterId()}`; + + Notifications.error( + ( +
+ Port Forwarding +

+ {msg} +

+
+
+
+ ), + { + id: notificationId, + timeout: 10_000, + }, + ); +} + diff --git a/src/renderer/port-forward/port-forward.store.ts b/src/renderer/port-forward/port-forward.store.ts index cf88ed9a4e..e19371a65e 100644 --- a/src/renderer/port-forward/port-forward.store.ts +++ b/src/renderer/port-forward/port-forward.store.ts @@ -24,10 +24,10 @@ import { action, makeObservable, observable, reaction } from "mobx"; import { ItemStore } from "../../common/item.store"; import { autoBind, createStorage, disposer } from "../utils"; import { ForwardedPort, PortForwardItem } from "./port-forward-item"; +import { notifyErrorPortForwarding } from "./port-forward-notify"; import { apiBase } from "../api"; import { waitUntilFree } from "tcp-port-used"; import logger from "../../common/logger"; -import { Notifications } from "../components/notifications"; export class PortForwardStore extends ItemStore { private storage = createStorage("port_forwards", undefined); @@ -49,11 +49,16 @@ export class PortForwardStore extends ItemStore { if (Array.isArray(savedPortForwards)) { logger.info("[PORT-FORWARD-STORE] starting saved port-forwards"); - const results = await Promise.allSettled(savedPortForwards.map(addPortForward)); + + // add the disabled ones + await Promise.all(savedPortForwards.filter(pf => pf.status === "Disabled").map(addPortForward)); + + // add the active ones and check if they started successfully + const results = await Promise.allSettled(savedPortForwards.filter(pf => pf.status === "Active").map(addPortForward)); for (const result of results) { - if (result.status === "rejected") { - Notifications.error("One or more port-forwards could not be started", { timeout: 10_000 }); + if (result.status === "rejected" || result.value.status === "Disabled") { + notifyErrorPortForwarding("One or more port-forwards could not be started"); return; } @@ -99,10 +104,6 @@ interface PortForwardResult { port: number; } -interface PortForwardsResult { - portForwards: ForwardedPort[]; -} - function portForwardsEqual(portForward: ForwardedPort) { return (pf: ForwardedPort) => ( pf.kind == portForward.kind && @@ -127,6 +128,16 @@ const setPortForward = action((portForward: ForwardedPort) => { portForwardStore.portForwards[index] = new PortForwardItem(portForward); }); +/** + * start an existing port-forward + * @param portForward the port-forward to start. If the forwardPort field is 0 then an arbitrary port will be + * used + * + * @returns the port-forward with updated status ("Active" if successfully started, "Disabled" otherwise) and + * forwardPort + * + * @throws if the port-forward does not already exist in the store + */ export const startPortForward = action( async (portForward: ForwardedPort): Promise => { const pf = findPortForward(portForward); @@ -160,6 +171,15 @@ export const startPortForward = action( async (portForward: ForwardedPort): Prom return pf as ForwardedPort; }); +/** + * add a port-forward to the store and optionally start it + * @param portForward the port-forward to add. If the port-forward already exists in the store it will be + * returned with its current state. If the forwardPort field is 0 then an arbitrary port will be + * used. If the status field is "Active" or not present then an attempt is made to start the port-forward. + * + * @returns the port-forward with updated status ("Active" if successfully started, "Disabled" otherwise) and + * forwardPort + */ export const addPortForward = action(async (portForward: ForwardedPort): Promise => { const pf = findPortForward(portForward); @@ -180,7 +200,7 @@ export const addPortForward = action(async (portForward: ForwardedPort): Promise return portForward; }); -export async function getActivePortForward(portForward: ForwardedPort): Promise { +async function getActivePortForward(portForward: ForwardedPort): Promise { const { port, forwardPort, protocol } = portForward; let response: PortForwardResult; @@ -196,6 +216,15 @@ export async function getActivePortForward(portForward: ForwardedPort): Promise< return portForward; } +/** + * get a port-forward from the store, with up-to-date status + * @param portForward the port-forward to get. + * + * @returns the port-forward with updated status ("Active" if running, "Disabled" if not) and + * forwardPort used. + * + * @throws if the port-forward does not exist in the store + */ export async function getPortForward(portForward: ForwardedPort): Promise { if (!findPortForward(portForward)) { throw new Error("port-forward not found"); @@ -217,6 +246,12 @@ export async function getPortForward(portForward: ForwardedPort): Promise => { const pf = findPortForward(portForward); @@ -232,6 +267,7 @@ export const modifyPortForward = action(async (portForward: ForwardedPort, desir } pf.forwardPort = desiredPort; + pf.protocol = portForward.protocol ?? "http"; setPortForward(pf); return await startPortForward(pf); @@ -244,6 +280,12 @@ export const modifyPortForward = action(async (portForward: ForwardedPort, desir }); +/** + * stop an existing port-forward. Its status is set to "Disabled" after successfully stopped. + * @param portForward the port-forward to stop. + * + * @throws if the port-forward could not be stopped. Its status is unchanged + */ export const stopPortForward = action(async (portForward: ForwardedPort) => { const pf = findPortForward(portForward); @@ -267,6 +309,10 @@ export const stopPortForward = action(async (portForward: ForwardedPort) => { setPortForward(pf); }); +/** + * remove and stop an existing port-forward. + * @param portForward the port-forward to remove. + */ export const removePortForward = action(async (portForward: ForwardedPort) => { const pf = findPortForward(portForward); @@ -293,18 +339,11 @@ export const removePortForward = action(async (portForward: ForwardedPort) => { } }); -export async function getActivePortForwards(clusterId?: string): Promise { - try { - const response = await apiBase.get("/pods/port-forwards", { query: { clusterId }}); - - return response.portForwards; - } catch (error) { - logger.warn(`[PORT-FORWARD-STORE] Error getting all port-forwards: ${error}`); - - return []; - } -} - +/** + * gets the list of port-forwards in the store + * + * @returns the port-forwards + */ export function getPortForwards(): ForwardedPort[] { return portForwardStore.portForwards; }