mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
addressed some review comments
Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>
This commit is contained in:
parent
0058e9f0e2
commit
6d63c39b11
@ -23,11 +23,10 @@ import type { RouteProps } from "react-router";
|
|||||||
import { buildURL } from "../utils/buildUrl";
|
import { buildURL } from "../utils/buildUrl";
|
||||||
|
|
||||||
export const portForwardsRoute: RouteProps = {
|
export const portForwardsRoute: RouteProps = {
|
||||||
path: "/port-forwards/:forwardport?"
|
path: "/port-forwards"
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface PortForwardsRouteParams {
|
export interface PortForwardsRouteParams {
|
||||||
forwardport?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const portForwardsURL = buildURL<PortForwardsRouteParams>(portForwardsRoute.path);
|
export const portForwardsURL = buildURL<PortForwardsRouteParams>(portForwardsRoute.path);
|
||||||
|
|||||||
@ -76,7 +76,7 @@ class PortForward {
|
|||||||
"port-forward",
|
"port-forward",
|
||||||
"-n", this.namespace,
|
"-n", this.namespace,
|
||||||
`${this.kind}/${this.name}`,
|
`${this.kind}/${this.name}`,
|
||||||
`${this.forwardPort??""}:${this.port}`
|
`${this.forwardPort ?? ""}:${this.port}`
|
||||||
];
|
];
|
||||||
|
|
||||||
this.process = spawn(kubectlBin, args, {
|
this.process = spawn(kubectlBin, args, {
|
||||||
@ -153,7 +153,7 @@ export class PortForwardRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
respondJson(response, {port: portForward.internalPort});
|
respondJson(response, { port: portForward.internalPort });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[PORT-FORWARD-ROUTE]: failed to open a port-forward: ${error}`, { namespace, port, resourceType, resourceName });
|
logger.error(`[PORT-FORWARD-ROUTE]: failed to open a port-forward: ${error}`, { namespace, port, resourceType, resourceName });
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ export class PortForwardRoute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async routeCurrentPortForward(request: LensApiRequest) {
|
static async routeCurrentPortForward(request: LensApiRequest) {
|
||||||
const { params, response, cluster} = request;
|
const { params, response, cluster } = request;
|
||||||
const { namespace, port, forwardPort, resourceType, resourceName } = params;
|
const { namespace, port, forwardPort, resourceType, resourceName } = params;
|
||||||
|
|
||||||
const portForward = PortForward.getPortforward({
|
const portForward = PortForward.getPortforward({
|
||||||
@ -172,32 +172,28 @@ export class PortForwardRoute {
|
|||||||
namespace, port, forwardPort
|
namespace, port, forwardPort
|
||||||
});
|
});
|
||||||
|
|
||||||
respondJson(response, {port: portForward?.internalPort?? null});
|
respondJson(response, { port: portForward?.internalPort ?? null });
|
||||||
}
|
}
|
||||||
|
|
||||||
static async routeAllPortForwards(request: LensApiRequest) {
|
static async routeAllPortForwards(request: LensApiRequest) {
|
||||||
const { response } = request;
|
const { response } = request;
|
||||||
|
|
||||||
const portForwards: PortForwardArgs[] = [];
|
const portForwards: PortForwardArgs[] = PortForward.portForwards.map(f => (
|
||||||
|
{
|
||||||
PortForward.portForwards.forEach(f => {
|
|
||||||
const pf: PortForwardArgs = {
|
|
||||||
clusterId: f.clusterId,
|
clusterId: f.clusterId,
|
||||||
kind: f.kind,
|
kind: f.kind,
|
||||||
namespace: f.namespace,
|
namespace: f.namespace,
|
||||||
name: f.name,
|
name: f.name,
|
||||||
port: f.port,
|
port: f.port,
|
||||||
forwardPort: f.forwardPort,
|
forwardPort: f.forwardPort,
|
||||||
};
|
})
|
||||||
|
);
|
||||||
|
|
||||||
portForwards.push(pf);
|
respondJson(response, { portForwards });
|
||||||
});
|
|
||||||
|
|
||||||
respondJson(response, {portForwards});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async routeCurrentPortForwardStop(request: LensApiRequest) {
|
static async routeCurrentPortForwardStop(request: LensApiRequest) {
|
||||||
const { params, response, cluster} = request;
|
const { params, response, cluster } = request;
|
||||||
const { namespace, port, forwardPort, resourceType, resourceName } = params;
|
const { namespace, port, forwardPort, resourceType, resourceName } = params;
|
||||||
|
|
||||||
const portForward = PortForward.getPortforward({
|
const portForward = PortForward.getPortforward({
|
||||||
@ -207,9 +203,13 @@ export class PortForwardRoute {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await portForward.stop();
|
await portForward.stop();
|
||||||
respondJson(response, {status: true});
|
respondJson(response, { status: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error);
|
logger.error("[PORT-FORWARD-ROUTE]: error stopping a port-forward", { namespace, port, forwardPort, resourceType, resourceName });
|
||||||
|
|
||||||
|
return respondJson(response, {
|
||||||
|
message: `error stopping a forward port ${port}`
|
||||||
|
}, 400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: $primary;
|
color: $primary;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.portInput {
|
.portInput {
|
||||||
|
|||||||
@ -24,8 +24,8 @@ import "./service-port-component.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import type { Service, ServicePort } from "../../../common/k8s-api/endpoints";
|
import type { Service, ServicePort } from "../../../common/k8s-api/endpoints";
|
||||||
import { observable, makeObservable, IReactionDisposer, reaction } from "mobx";
|
import { observable, makeObservable, reaction } from "mobx";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames, disposer } from "../../utils";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { addPortForward, getPortForward, openPortForward, PortForwardDialog, portForwardStore, removePortForward } from "../../port-forward";
|
import { addPortForward, getPortForward, openPortForward, PortForwardDialog, portForwardStore, removePortForward } from "../../port-forward";
|
||||||
@ -57,11 +57,9 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch() {
|
watch() {
|
||||||
const disposers: IReactionDisposer[] = [
|
return disposer(
|
||||||
reaction(() => portForwardStore.portForwards, () => this.init()),
|
reaction(() => portForwardStore.portForwards, () => this.init()),
|
||||||
];
|
);
|
||||||
|
|
||||||
return () => disposers.forEach((dispose) => dispose());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -113,7 +111,7 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
openPortForward(portForward);
|
openPortForward(portForward);
|
||||||
this.isPortForwarded = true;
|
this.isPortForwarded = true;
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
Notifications.error(error);
|
Notifications.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
@ -135,7 +133,7 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
try {
|
try {
|
||||||
await removePortForward(portForward);
|
await removePortForward(portForward);
|
||||||
this.isPortForwarded = false;
|
this.isPortForwarded = false;
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
Notifications.error(error);
|
Notifications.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
@ -148,7 +146,7 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
const portForwardAction = async () => {
|
const portForwardAction = async () => {
|
||||||
if (this.isPortForwarded) {
|
if (this.isPortForwarded) {
|
||||||
await this.stopPortForward();
|
await this.stopPortForward();
|
||||||
}else {
|
} else {
|
||||||
const portForward: ForwardedPort = {
|
const portForward: ForwardedPort = {
|
||||||
kind: "service",
|
kind: "service",
|
||||||
name: service.getName(),
|
name: service.getName(),
|
||||||
@ -157,20 +155,19 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
forwardPort: this.forwardPort.toString()
|
forwardPort: this.forwardPort.toString()
|
||||||
};
|
};
|
||||||
|
|
||||||
PortForwardDialog.open(portForward, true);
|
PortForwardDialog.open(portForward, { openInBrowser: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("ServicePortComponent", { waiting: this.waiting })}>
|
<div className={cssNames("ServicePortComponent", { waiting: this.waiting })}>
|
||||||
<span title="Open in a browser" onClick={() => this.portForward() }>
|
<span title="Open in a browser" onClick={() => this.portForward()}>
|
||||||
{port.toString()}
|
{port.toString()}
|
||||||
|
</span>
|
||||||
|
<Button onClick={() => portForwardAction()}> {this.isPortForwarded ? "Stop" : "Forward..."} </Button>
|
||||||
{this.waiting && (
|
{this.waiting && (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
)}
|
)}
|
||||||
</span>
|
|
||||||
{" "}
|
|
||||||
<Button onClick={() => portForwardAction()}> {this.isPortForwarded ? "Stop":"Forward..."} </Button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
color: $primary;
|
color: $primary;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.portInput {
|
.portInput {
|
||||||
|
|||||||
@ -117,7 +117,7 @@ export class PodContainerPort extends React.Component<Props> {
|
|||||||
openPortForward(portForward);
|
openPortForward(portForward);
|
||||||
this.isPortForwarded = true;
|
this.isPortForwarded = true;
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
Notifications.error(error);
|
Notifications.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
@ -139,7 +139,7 @@ export class PodContainerPort extends React.Component<Props> {
|
|||||||
try {
|
try {
|
||||||
await removePortForward(portForward);
|
await removePortForward(portForward);
|
||||||
this.isPortForwarded = false;
|
this.isPortForwarded = false;
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
Notifications.error(error);
|
Notifications.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
@ -163,20 +163,19 @@ export class PodContainerPort extends React.Component<Props> {
|
|||||||
forwardPort: this.forwardPort.toString()
|
forwardPort: this.forwardPort.toString()
|
||||||
};
|
};
|
||||||
|
|
||||||
PortForwardDialog.open(portForward, true);
|
PortForwardDialog.open(portForward, { openInBrowser: true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("PodContainerPort", { waiting: this.waiting })}>
|
<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}
|
{text}
|
||||||
|
</span>
|
||||||
|
<Button onClick={() => portForwardAction()}> {this.isPortForwarded ? "Stop" : "Forward..."} </Button>
|
||||||
{this.waiting && (
|
{this.waiting && (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
)}
|
)}
|
||||||
</span>
|
|
||||||
{" "}
|
|
||||||
<Button onClick={() => portForwardAction()}> {this.isPortForwarded ? "Stop":"Forward..."} </Button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
import "./port-forward-dialog.scss";
|
import "./port-forward-dialog.scss";
|
||||||
|
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { computed, observable, makeObservable } from "mobx";
|
import { observable, makeObservable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Dialog, DialogProps } from "../components/dialog";
|
import { Dialog, DialogProps } from "../components/dialog";
|
||||||
import { Wizard, WizardStep } from "../components/wizard";
|
import { Wizard, WizardStep } from "../components/wizard";
|
||||||
@ -30,12 +30,16 @@ import { Input } from "../components/input";
|
|||||||
import { Notifications } from "../components/notifications";
|
import { Notifications } from "../components/notifications";
|
||||||
import { cssNames } from "../utils";
|
import { cssNames } from "../utils";
|
||||||
import { addPortForward, modifyPortForward } from "./port-forward.store";
|
import { addPortForward, modifyPortForward } from "./port-forward.store";
|
||||||
import type { ForwardedPort } from "./port-forward.store";
|
import type { ForwardedPort } from "./port-forward-item";
|
||||||
import { openPortForward } from ".";
|
import { openPortForward } from ".";
|
||||||
|
|
||||||
interface Props extends Partial<DialogProps> {
|
interface Props extends Partial<DialogProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PortForwardDialogOpenOptions {
|
||||||
|
openInBrowser: boolean
|
||||||
|
}
|
||||||
|
|
||||||
const dialogState = observable.object({
|
const dialogState = observable.object({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
data: null as ForwardedPort,
|
data: null as ForwardedPort,
|
||||||
@ -53,10 +57,10 @@ export class PortForwardDialog extends Component<Props> {
|
|||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static open(portForward: ForwardedPort, openInBrowser = false) {
|
static open(portForward: ForwardedPort, options : PortForwardDialogOpenOptions = { openInBrowser: false }) {
|
||||||
dialogState.isOpen = true;
|
dialogState.isOpen = true;
|
||||||
dialogState.data = portForward;
|
dialogState.data = portForward;
|
||||||
dialogState.openInBrowser = openInBrowser;
|
dialogState.openInBrowser = options.openInBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
static close() {
|
static close() {
|
||||||
@ -71,15 +75,6 @@ export class PortForwardDialog extends Component<Props> {
|
|||||||
PortForwardDialog.close();
|
PortForwardDialog.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
@computed get scaleMax() {
|
|
||||||
const { currentPort } = this;
|
|
||||||
const defaultMax = 50;
|
|
||||||
|
|
||||||
return currentPort <= defaultMax
|
|
||||||
? defaultMax * 2
|
|
||||||
: currentPort * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpen = async () => {
|
onOpen = async () => {
|
||||||
const { portForward } = this;
|
const { portForward } = this;
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,15 @@
|
|||||||
import type { ItemObject } from "../../common/item.store";
|
import type { ItemObject } from "../../common/item.store";
|
||||||
import { autoBind } from "../../common/utils";
|
import { autoBind } from "../../common/utils";
|
||||||
|
|
||||||
|
export interface ForwardedPort {
|
||||||
|
clusterId?: string;
|
||||||
|
kind: string;
|
||||||
|
namespace: string;
|
||||||
|
name: string;
|
||||||
|
port: string;
|
||||||
|
forwardPort: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class PortForwardItem implements ItemObject {
|
export class PortForwardItem implements ItemObject {
|
||||||
clusterId: string;
|
clusterId: string;
|
||||||
kind: string;
|
kind: string;
|
||||||
@ -31,7 +40,14 @@ export class PortForwardItem implements ItemObject {
|
|||||||
port: string;
|
port: string;
|
||||||
forwardPort: string;
|
forwardPort: string;
|
||||||
|
|
||||||
constructor() {
|
constructor(pf: ForwardedPort) {
|
||||||
|
this.clusterId = pf.clusterId;
|
||||||
|
this.kind = pf.kind;
|
||||||
|
this.namespace = pf.namespace;
|
||||||
|
this.name = pf.name;
|
||||||
|
this.port = pf.port;
|
||||||
|
this.forwardPort = pf.forwardPort;
|
||||||
|
|
||||||
autoBind(this);
|
autoBind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,24 +20,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import { computed, IReactionDisposer, makeObservable, observable, reaction } from "mobx";
|
import { makeObservable, observable, reaction } from "mobx";
|
||||||
import { ItemObject, ItemStore } from "../../common/item.store";
|
import { ItemStore } from "../../common/item.store";
|
||||||
import { autoBind, createStorage, getHostedClusterId, openExternal } from "../utils";
|
import { autoBind, createStorage, disposer, getHostedClusterId, openExternal } from "../utils";
|
||||||
import { PortForwardItem } from "./port-forward-item";
|
import { ForwardedPort, PortForwardItem } from "./port-forward-item";
|
||||||
import { apiBase } from "../api";
|
import { apiBase } from "../api";
|
||||||
import { waitUntilFree } from "tcp-port-used";
|
import { waitUntilFree } from "tcp-port-used";
|
||||||
import { Notifications } from "../components/notifications";
|
import { Notifications } from "../components/notifications";
|
||||||
import logger from "../../common/logger";
|
import logger from "../../common/logger";
|
||||||
|
|
||||||
export interface ForwardedPort {
|
|
||||||
clusterId?: string;
|
|
||||||
kind: string;
|
|
||||||
namespace: string;
|
|
||||||
name: string;
|
|
||||||
port: string;
|
|
||||||
forwardPort: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PortForwardStore extends ItemStore<PortForwardItem> {
|
export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||||
private storage = createStorage<ForwardedPort[] | undefined>("port_forwards", undefined);
|
private storage = createStorage<ForwardedPort[] | undefined>("port_forwards", undefined);
|
||||||
|
|
||||||
@ -56,36 +47,18 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
|||||||
|
|
||||||
if (Array.isArray(savedPortForwards)) {
|
if (Array.isArray(savedPortForwards)) {
|
||||||
logger.info("[PORT_FORWARD] starting saved port-forwards");
|
logger.info("[PORT_FORWARD] starting saved port-forwards");
|
||||||
await Promise.all(savedPortForwards.map(pf => {
|
await Promise.all(savedPortForwards.map(addPortForward));
|
||||||
const port = new PortForwardItem;
|
|
||||||
|
|
||||||
port.clusterId = pf.clusterId;
|
this.reset();
|
||||||
port.kind = pf.kind;
|
|
||||||
port.namespace = pf.namespace;
|
|
||||||
port.name = pf.name;
|
|
||||||
port.port = pf.port;
|
|
||||||
port.forwardPort = pf.forwardPort;
|
|
||||||
|
|
||||||
return addPortForward(port);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.portForwards = [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@observable selectedItemId?: string;
|
|
||||||
@observable portForwards: PortForwardItem[];
|
@observable portForwards: PortForwardItem[];
|
||||||
|
|
||||||
@computed get selectedItem() {
|
|
||||||
return this.portForwards.find((e: ItemObject) => e.getId() === this.selectedItemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch() {
|
watch() {
|
||||||
const disposers: IReactionDisposer[] = [
|
return disposer(
|
||||||
reaction(() => this.portForwards, () => this.loadAll()),
|
reaction(() => this.portForwards, () => this.loadAll()),
|
||||||
];
|
);
|
||||||
|
|
||||||
return () => disposers.forEach((dispose) => dispose());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadAll() {
|
loadAll() {
|
||||||
@ -93,21 +66,11 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
|||||||
let portForwards = await getPortForwards();
|
let portForwards = await getPortForwards();
|
||||||
|
|
||||||
// filter out any not for this cluster
|
// filter out any not for this cluster
|
||||||
portForwards = portForwards?.filter(pf => pf.clusterId == getHostedClusterId());
|
portForwards = portForwards.filter(pf => pf.clusterId == getHostedClusterId());
|
||||||
this.storage.set(portForwards);
|
this.storage.set(portForwards);
|
||||||
|
|
||||||
this.reset();
|
this.reset();
|
||||||
portForwards?.forEach(pf => {
|
portForwards.map(pf => this.portForwards.push(new PortForwardItem(pf)));
|
||||||
const port = new PortForwardItem;
|
|
||||||
|
|
||||||
port.clusterId = pf.clusterId;
|
|
||||||
port.kind = pf.kind;
|
|
||||||
port.namespace = pf.namespace;
|
|
||||||
port.name = pf.name;
|
|
||||||
port.port = pf.port;
|
|
||||||
port.forwardPort = pf.forwardPort;
|
|
||||||
this.portForwards.push(port);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.portForwards;
|
return this.portForwards;
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user