From fbbe728fba0c5c7b6756d569e7fc5a2471f9c068 Mon Sep 17 00:00:00 2001 From: Jim Ehrismann Date: Fri, 17 Dec 2021 20:37:25 -0500 Subject: [PATCH] working Signed-off-by: Jim Ehrismann --- .../service-port-component.tsx | 21 +++- .../+workloads-pods/pod-container-port.tsx | 14 ++- .../port-forward/port-forward-dialog.tsx | 3 +- .../port-forward/port-forward-item.ts | 2 +- .../port-forward/port-forward.store.ts | 118 ++++++++++++------ 5 files changed, 107 insertions(+), 51 deletions(-) diff --git a/src/renderer/components/+network-services/service-port-component.tsx b/src/renderer/components/+network-services/service-port-component.tsx index e058039440..d0bcecb9b7 100644 --- a/src/renderer/components/+network-services/service-port-component.tsx +++ b/src/renderer/components/+network-services/service-port-component.tsx @@ -24,11 +24,11 @@ import "./service-port-component.scss"; import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; import type { Service, ServicePort } from "../../../common/k8s-api/endpoints"; -import { observable, makeObservable, reaction } from "mobx"; +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, portForwardStore, predictProtocol, removePortForward } from "../../port-forward"; +import { aboutPortForwarding, addPortForward, forwardedPortStatus, getPortForward, getPortForwards, getPortForwardStatus, openPortForward, PortForwardDialog, portForwardStore, predictProtocol, removePortForward } from "../../port-forward"; import type { ForwardedPort } from "../../port-forward"; import { Spinner } from "../spinner"; @@ -66,19 +66,28 @@ export class ServicePortComponent extends React.Component { }; let activePort: number; + let status: forwardedPortStatus; + + console.log("checkExistingPortForwarding()"); try { activePort = await getPortForward(portForward) ?? 0; + status = await getPortForwardStatus(portForward); } catch (error) { this.isPortForwarded = false; + console.log("(catch) isPortForwarded:", this.isPortForwarded, this.forwardPort); + return; } this.forwardPort = activePort; - this.isPortForwarded = activePort ? true : false; + this.isPortForwarded = (status === "Active" && activePort) ? true : false; + + console.log("isPortForwarded:", this.isPortForwarded, this.forwardPort); } + @action async portForward() { const { service, port } = this.props; const portForward: ForwardedPort = { @@ -88,13 +97,14 @@ export class ServicePortComponent extends React.Component { port: port.port, forwardPort: this.forwardPort, protocol: predictProtocol(port.name), + status: "Active", }; this.waiting = true; try { // determine how many port-forwards already exist - const { length } = await getPortForwards(); + const { length } = getPortForwards(); this.forwardPort = await addPortForward(portForward); @@ -116,6 +126,7 @@ export class ServicePortComponent extends React.Component { } } + @action async stopPortForward() { const { service, port } = this.props; const portForward: ForwardedPort = { @@ -128,6 +139,8 @@ export class ServicePortComponent extends React.Component { this.waiting = true; + console.log("stopPortForward()"); + try { await removePortForward(portForward); this.isPortForwarded = false; diff --git a/src/renderer/components/+workloads-pods/pod-container-port.tsx b/src/renderer/components/+workloads-pods/pod-container-port.tsx index df25fae95e..79b55ee271 100644 --- a/src/renderer/components/+workloads-pods/pod-container-port.tsx +++ b/src/renderer/components/+workloads-pods/pod-container-port.tsx @@ -24,12 +24,11 @@ import "./pod-container-port.scss"; import React from "react"; import { disposeOnUnmount, observer } from "mobx-react"; import type { Pod } from "../../../common/k8s-api/endpoints"; -import { observable, makeObservable, reaction } from "mobx"; +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, portForwardStore, predictProtocol, removePortForward } from "../../port-forward"; -import type { ForwardedPort } from "../../port-forward"; +import { aboutPortForwarding, addPortForward, forwardedPortStatus, getPortForward, getPortForwards, getPortForwardStatus, openPortForward, PortForwardDialog, portForwardStore, predictProtocol, removePortForward } from "../../port-forward";import type { ForwardedPort } from "../../port-forward"; import { Spinner } from "../spinner"; interface Props { @@ -70,9 +69,11 @@ export class PodContainerPort extends React.Component { }; let activePort: number; + let status: forwardedPortStatus; try { activePort = await getPortForward(portForward) ?? 0; + status = await getPortForwardStatus(portForward); } catch (error) { this.isPortForwarded = false; @@ -80,9 +81,10 @@ export class PodContainerPort extends React.Component { } this.forwardPort = activePort; - this.isPortForwarded = activePort ? true : false; + this.isPortForwarded = (status === "Active" && activePort) ? true : false; } + @action async portForward() { const { pod, port } = this.props; const portForward: ForwardedPort = { @@ -92,13 +94,14 @@ export class PodContainerPort extends React.Component { port: port.containerPort, forwardPort: this.forwardPort, protocol: predictProtocol(port.name), + status: "Active", }; this.waiting = true; try { // determine how many port-forwards already exist - const { length } = await getPortForwards(); + const { length } = getPortForwards(); this.forwardPort = await addPortForward(portForward); @@ -120,6 +123,7 @@ export class PodContainerPort extends React.Component { } } + @action async stopPortForward() { const { pod, port } = this.props; const portForward: ForwardedPort = { diff --git a/src/renderer/port-forward/port-forward-dialog.tsx b/src/renderer/port-forward/port-forward-dialog.tsx index 51f9b2d902..44df442f60 100644 --- a/src/renderer/port-forward/port-forward-dialog.tsx +++ b/src/renderer/port-forward/port-forward-dialog.tsx @@ -97,11 +97,12 @@ export class PortForwardDialog extends Component { try { // determine how many port-forwards already exist - const { length } = await getPortForwards(); + const { length } = getPortForwards(); let port: number; portForward.protocol = dialogState.useHttps ? "https" : "http"; + portForward.status = "Active"; if (currentPort) { port = await modifyPortForward(portForward, desiredPort); diff --git a/src/renderer/port-forward/port-forward-item.ts b/src/renderer/port-forward/port-forward-item.ts index 0135912e84..3acbca5a6a 100644 --- a/src/renderer/port-forward/port-forward-item.ts +++ b/src/renderer/port-forward/port-forward-item.ts @@ -50,7 +50,7 @@ export class PortForwardItem implements ItemObject { this.port = pf.port; this.forwardPort = pf.forwardPort; this.protocol = pf.protocol ?? "http"; - this.status = pf.status; + this.status = pf.status ?? "Active"; autoBind(this); } diff --git a/src/renderer/port-forward/port-forward.store.ts b/src/renderer/port-forward/port-forward.store.ts index 61efeec201..566b921965 100644 --- a/src/renderer/port-forward/port-forward.store.ts +++ b/src/renderer/port-forward/port-forward.store.ts @@ -20,10 +20,10 @@ */ -import { makeObservable, observable, reaction } from "mobx"; +import { action, makeObservable, observable, reaction } from "mobx"; import { ItemStore } from "../../common/item.store"; -import { autoBind, createStorage, disposer, getHostedClusterId } from "../utils"; -import { ForwardedPort, PortForwardItem } from "./port-forward-item"; +import { autoBind, createStorage, disposer } from "../utils"; +import { ForwardedPort, forwardedPortStatus, PortForwardItem } from "./port-forward-item"; import { apiBase } from "../api"; import { waitUntilFree } from "tcp-port-used"; import logger from "../../common/logger"; @@ -63,13 +63,13 @@ export class PortForwardStore extends ItemStore { watch() { return disposer( - reaction(() => this.portForwards.slice(), () => this.loadAll()), + reaction(() => portForwardStore.portForwards.slice(), () => portForwardStore.loadAll()), ); } loadAll() { - return this.loadItems(async () => { - const portForwards = await getPortForwards(getHostedClusterId()); + return this.loadItems(() => { + const portForwards = getPortForwards(); this.storage.set(portForwards); @@ -113,11 +113,21 @@ function portForwardsEqual(portForward: ForwardedPort) { } function findPortForward(portForward: ForwardedPort) { - return (portForwardStore.portForwards.find(portForwardsEqual(portForward))); + return portForwardStore.portForwards.find(portForwardsEqual(portForward)); } -export async function startPortForward(portForward: ForwardedPort): Promise { +const setPortForward = action((portForward: ForwardedPort) => { + const index = portForwardStore.portForwards.findIndex(portForwardsEqual(portForward)); + + if (index < 0 ) { + return; + } + + portForwardStore.portForwards[index] = new PortForwardItem(portForward); +}); + +export const startPortForward = action( async (portForward: ForwardedPort): Promise => { const pf = findPortForward(portForward); if (!pf) { @@ -127,31 +137,34 @@ export async function startPortForward(portForward: ForwardedPort): Promise(`/pods/port-forward/${portForward.namespace}/${portForward.kind}/${portForward.name}`, { query: { port, forwardPort, protocol }}); + response = await apiBase.post(`/pods/port-forward/${pf.namespace}/${pf.kind}/${pf.name}`, { query: { port, forwardPort, protocol }}); // expecting the received port to be the specified port, unless the specified port is 0, which indicates any available port is suitable - if (portForward.forwardPort && response?.port && response.port != +portForward.forwardPort) { - logger.warn(`[PORT-FORWARD-STORE] specified ${portForward.forwardPort}, got ${response.port}`); + if (pf.forwardPort && response?.port && response.port != +pf.forwardPort) { + logger.warn(`[PORT-FORWARD-STORE] specified ${pf.forwardPort}, got ${response.port}`); } pf.forwardPort = response.port; pf.status = "Active"; + } catch (error) { - logger.warn("[PORT-FORWARD-STORE] Error adding port-forward:", error, portForward); + logger.warn("[PORT-FORWARD-STORE] Error starting port-forward:", error, pf); pf.status = "Disabled"; throw (error); + } finally { + setPortForward(pf); } return response?.port; -} +}); -export async function addPortForward(portForward: ForwardedPort): Promise { +export const addPortForward = action(async (portForward: ForwardedPort): Promise => { const pf = findPortForward(portForward); if (pf) { @@ -171,12 +184,12 @@ export async function addPortForward(portForward: ForwardedPort): Promise { const { port, forwardPort, protocol } = portForward; @@ -197,30 +210,43 @@ export async function getPortForward(portForward: ForwardedPort): Promise { +export async function getPortForwardStatus(portForward: ForwardedPort): Promise { + + const pf = findPortForward(portForward); + + if (!pf) { + throw new Error("port-forward not found"); + } + + try { + await getActivePortForward(portForward); + + } catch (error) { + // port is not active + return "Disabled"; + } + + return pf.status; +} + +export const modifyPortForward = action(async (portForward: ForwardedPort, desiredPort: number): Promise => { let port = 0; await removePortForward(portForward); @@ -228,10 +254,10 @@ export async function modifyPortForward(portForward: ForwardedPort, desiredPort: port = await addPortForward(portForward); return port; -} +}); -export async function stopPortForward(portForward: ForwardedPort) { +export const stopPortForward = action(async (portForward: ForwardedPort) => { const pf = findPortForward(portForward); if (!pf) { @@ -253,9 +279,10 @@ export async function stopPortForward(portForward: ForwardedPort) { } pf.status = "Disabled"; -} + setPortForward(pf); +}); -export async function removePortForward(portForward: ForwardedPort) { +export const removePortForward = action(async (portForward: ForwardedPort) => { const pf = findPortForward(portForward); if (!pf) { @@ -273,8 +300,15 @@ export async function removePortForward(portForward: ForwardedPort) { logger.warn("[PORT-FORWARD-STORE] Error removing port-forward:", error, portForward); } } - portForwardStore.portForwards = portForwardStore.portForwards.filter(item => item !== pf); -} + + const index = portForwardStore.portForwards.findIndex(portForwardsEqual(portForward)); + + if (index >= 0 ) { + console.log("removePortForward splice", index, portForwardStore.portForwards[index]); + portForwardStore.portForwards.splice(index, 1); + console.log("portForwards after splice", portForwardStore.portForwards); + } +}); export async function getActivePortForwards(clusterId?: string): Promise { try { @@ -288,15 +322,19 @@ export async function getActivePortForwards(clusterId?: string): Promise { +export function getPortForwards(): ForwardedPort[] { + return portForwardStore.portForwards; +} + +export const getPortForwardsStatus = action(async (clusterId?: string): Promise => { try { // get the active port-forwards to update the status const activePortForwards = await getActivePortForwards(clusterId); portForwardStore.portForwards.map((item, index) => { - if (activePortForwards.find(portForwardsEqual(item))) { + if (activePortForwards.find(portForwardsEqual(item)) && portForwardStore.portForwards[index].status !== "Active") { portForwardStore.portForwards[index].status = "Active"; - } else { + } else if (portForwardStore.portForwards[index].status !== "Disabled") { portForwardStore.portForwards[index].status = "Disabled"; } }); @@ -305,6 +343,6 @@ export async function getPortForwards(clusterId?: string): Promise