mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Feature/port forward dashboard (#3922)
* Added ability to add custom port on pod and service port forwarding (#3295) * Added ability to add custom port on pod and service port forwarding Signed-off-by: rdeepc <12953177+rdeepc@users.noreply.github.com> * Added ability to add custom port on pod and service port forwarding - pod-container-port fixed init async and active port checking - service-port-component fixed init async and active port checking - port-forward-route promise and response fix Signed-off-by: rdeepc <12953177+rdeepc@users.noreply.github.com> * Added ability to add custom port on pod and service port forwarding Signed-off-by: rdeepc <12953177+rdeepc@users.noreply.github.com> * - Added Custom Port Selection for port forwarding - Implemented Random Port if custom port is not provided Signed-off-by: rdeepc <12953177+rdeepc@users.noreply.github.com> Co-authored-by: Saumya Shovan Roy <saumyashovanroy@gmail.com> * cherry-pick of hackweek work plus merge conflicts/build errors added a route to get all port forwards Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> Added Forwarded Ports to cluster dashboard Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> working port-forward page (open, edit, remove) Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> added local storage to the port-forward store Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> automatically restore port-forward after pod is restarted Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> start port-forwards using random local port by default, rearranged pod and service port-forward UI Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * refactor Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * more refactoring, don't always open port-forwards in browser, refined reused port-forward dialog Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * removed unimplemented forwarded port details page,modified logging Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * addressed some review comments Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * made port and forwardPort query params and cleaned up port-forward routing paths Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * address more review comments and change dashboard tab name to 'Port Forwarding' Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * changed port and forwardPort fields to be Numbers Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * removed extraneous reset() call, reorder field declarations Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * port-forward now gets the bundled kubectl path without going through the 'ensureKubectl' hoops Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * more cleanup/tweaking Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> * fix bug where port-forward info did not update on pod details page when different pod (in same deployment?) is clicked Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com> Co-authored-by: Saumya Shovan Roy (Deep) <12953177+rdeepc@users.noreply.github.com> Co-authored-by: Saumya Shovan Roy <saumyashovanroy@gmail.com>
This commit is contained in:
22 files changed
+1137
-73
No files matched your search
@@ -22,12 +22,15 @@
|
||||
import "./pod-container-port.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import type { Pod } from "../../../common/k8s-api/endpoints";
|
||||
import { apiBase } from "../../api";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observable, makeObservable, reaction } from "mobx";
|
||||
import { cssNames } from "../../utils";
|
||||
import { Notifications } from "../notifications";
|
||||
import { Button } from "../button";
|
||||
import { addPortForward, getPortForward, openPortForward, PortForwardDialog, portForwardStore, removePortForward } from "../../port-forward";
|
||||
import type { ForwardedPort } from "../../port-forward";
|
||||
import logger from "../../../common/logger";
|
||||
import { Spinner } from "../spinner";
|
||||
|
||||
interface Props {
|
||||
@@ -42,20 +45,86 @@ interface Props {
|
||||
@observer
|
||||
export class PodContainerPort extends React.Component<Props> {
|
||||
@observable waiting = false;
|
||||
@observable forwardPort = 0;
|
||||
@observable isPortForwarded = false;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
this.init();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => [ portForwardStore.portForwards, this.props.pod ], () => this.init()),
|
||||
]);
|
||||
}
|
||||
|
||||
init() {
|
||||
this.checkExistingPortForwarding().catch(error => {
|
||||
logger.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
async checkExistingPortForwarding() {
|
||||
const { pod, port } = this.props;
|
||||
const portForward: ForwardedPort = {
|
||||
kind: "pod",
|
||||
name: pod.getName(),
|
||||
namespace: pod.getNs(),
|
||||
port: port.containerPort,
|
||||
forwardPort: this.forwardPort,
|
||||
};
|
||||
const activePort = await getPortForward(portForward) ?? 0;
|
||||
|
||||
this.forwardPort = activePort;
|
||||
this.isPortForwarded = activePort ? true : false;
|
||||
}
|
||||
|
||||
async portForward() {
|
||||
const { pod, port } = this.props;
|
||||
const portForward: ForwardedPort = {
|
||||
kind: "pod",
|
||||
name: pod.getName(),
|
||||
namespace: pod.getNs(),
|
||||
port: port.containerPort,
|
||||
forwardPort: this.forwardPort,
|
||||
};
|
||||
|
||||
this.waiting = true;
|
||||
this.isPortForwarded = false;
|
||||
|
||||
try {
|
||||
this.forwardPort = await addPortForward(portForward);
|
||||
|
||||
if (this.forwardPort) {
|
||||
portForward.forwardPort = this.forwardPort;
|
||||
openPortForward(portForward);
|
||||
this.isPortForwarded = true;
|
||||
}
|
||||
} catch (error) {
|
||||
Notifications.error(error);
|
||||
} finally {
|
||||
this.waiting = false;
|
||||
}
|
||||
}
|
||||
|
||||
async stopPortForward() {
|
||||
const { pod, port } = this.props;
|
||||
const portForward: ForwardedPort = {
|
||||
kind: "pod",
|
||||
name: pod.getName(),
|
||||
namespace: pod.getNs(),
|
||||
port: port.containerPort,
|
||||
forwardPort: this.forwardPort,
|
||||
};
|
||||
|
||||
this.waiting = true;
|
||||
|
||||
try {
|
||||
await apiBase.post(`/pods/${pod.getNs()}/pod/${pod.getName()}/port-forward/${port.containerPort}`, {});
|
||||
} catch(error) {
|
||||
await removePortForward(portForward);
|
||||
this.isPortForwarded = false;
|
||||
} catch (error) {
|
||||
Notifications.error(error);
|
||||
} finally {
|
||||
this.waiting = false;
|
||||
@@ -63,18 +132,35 @@ export class PodContainerPort extends React.Component<Props> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { port } = this.props;
|
||||
const { pod, port } = this.props;
|
||||
const { name, containerPort, protocol } = port;
|
||||
const text = `${name ? `${name}: ` : ""}${containerPort}/${protocol}`;
|
||||
|
||||
const portForwardAction = async () => {
|
||||
if (this.isPortForwarded) {
|
||||
await this.stopPortForward();
|
||||
} else {
|
||||
const portForward: ForwardedPort = {
|
||||
kind: "pod",
|
||||
name: pod.getName(),
|
||||
namespace: pod.getNs(),
|
||||
port: port.containerPort,
|
||||
forwardPort: this.forwardPort,
|
||||
};
|
||||
|
||||
PortForwardDialog.open(portForward, { openInBrowser: true });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cssNames("PodContainerPort", { waiting: this.waiting })}>
|
||||
<span title="Open in a browser" onClick={() => this.portForward() }>
|
||||
<span title="Open in a browser" onClick={() => this.portForward()}>
|
||||
{text}
|
||||
{this.waiting && (
|
||||
<Spinner />
|
||||
)}
|
||||
</span>
|
||||
<Button onClick={() => portForwardAction()}> {this.isPortForwarded ? "Stop" : "Forward..."} </Button>
|
||||
{this.waiting && (
|
||||
<Spinner />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user