mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Cascade different refactorings to eliminate global shared state from app paths
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
1 parent
908a40975e
commit
9d33fff906
336 files changed
+9105
-3307
No files matched your search
@@ -19,7 +19,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
export * from "./port-forward.store";
|
||||
export * from "./port-forward-store/port-forward-store";
|
||||
export * from "./port-forward-item";
|
||||
export * from "./port-forward-dialog";
|
||||
export * from "./port-forward-notify";
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { PortForwardDialogModel } from "./port-forward-dialog-model";
|
||||
|
||||
const portForwardDialogModelInjectable = getInjectable({
|
||||
instantiate: () => new PortForwardDialogModel(),
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default portForwardDialogModelInjectable;
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { action, computed, observable, makeObservable } from "mobx";
|
||||
import type { ForwardedPort } from "../port-forward-item";
|
||||
|
||||
interface PortForwardDialogOpenOptions {
|
||||
openInBrowser: boolean
|
||||
}
|
||||
|
||||
export class PortForwardDialogModel {
|
||||
portForward: ForwardedPort = null;
|
||||
useHttps = false;
|
||||
openInBrowser = false;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
isOpen: computed,
|
||||
portForward: observable,
|
||||
useHttps: observable,
|
||||
openInBrowser: observable,
|
||||
|
||||
open: action,
|
||||
close: action,
|
||||
});
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return !!this.portForward;
|
||||
}
|
||||
|
||||
open = (portForward: ForwardedPort, options: PortForwardDialogOpenOptions = { openInBrowser: false }) => {
|
||||
this.portForward = portForward;
|
||||
this.useHttps = portForward.protocol === "https";
|
||||
this.openInBrowser = options.openInBrowser;
|
||||
};
|
||||
|
||||
close = () => {
|
||||
this.portForward = null;
|
||||
this.useHttps = false;
|
||||
this.openInBrowser = false;
|
||||
};
|
||||
}
|
||||
@@ -29,58 +29,37 @@ import { Wizard, WizardStep } from "../components/wizard";
|
||||
import { Input } from "../components/input";
|
||||
import { Notifications } from "../components/notifications";
|
||||
import { cssNames } from "../utils";
|
||||
import { addPortForward, getPortForwards, modifyPortForward } from "./port-forward.store";
|
||||
import { getPortForwards } from "./port-forward-store/port-forward-store";
|
||||
import type { ForwardedPort } from "./port-forward-item";
|
||||
import { aboutPortForwarding, openPortForward } from ".";
|
||||
import { Checkbox } from "../components/checkbox";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import modifyPortForwardInjectable from "./port-forward-store/modify-port-forward/modify-port-forward.injectable";
|
||||
import type { PortForwardDialogModel } from "./port-forward-dialog-model/port-forward-dialog-model";
|
||||
import portForwardDialogModelInjectable from "./port-forward-dialog-model/port-forward-dialog-model.injectable";
|
||||
import addPortForwardInjectable from "./port-forward-store/add-port-forward/add-port-forward.injectable";
|
||||
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
interface PortForwardDialogOpenOptions {
|
||||
openInBrowser: boolean
|
||||
interface Dependencies {
|
||||
modifyPortForward: (item: ForwardedPort, desiredPort: number) => Promise<number>,
|
||||
addPortForward: (item: ForwardedPort) => Promise<number>,
|
||||
model: PortForwardDialogModel
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as ForwardedPort,
|
||||
useHttps: false,
|
||||
openInBrowser: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class PortForwardDialog extends Component<Props> {
|
||||
class NonInjectedPortForwardDialog extends Component<Props & Dependencies> {
|
||||
@observable currentPort = 0;
|
||||
@observable desiredPort = 0;
|
||||
|
||||
constructor(props: Props) {
|
||||
constructor(props: Props & Dependencies) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(portForward: ForwardedPort, options: PortForwardDialogOpenOptions = { openInBrowser: false }) {
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = portForward;
|
||||
dialogState.useHttps = portForward.protocol === "https";
|
||||
dialogState.openInBrowser = options.openInBrowser;
|
||||
}
|
||||
|
||||
static close() {
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get portForward() {
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
PortForwardDialog.close();
|
||||
};
|
||||
|
||||
onOpen = async () => {
|
||||
const { portForward } = this;
|
||||
|
||||
this.currentPort = +portForward.forwardPort;
|
||||
this.currentPort = +this.props.model.portForward.forwardPort;
|
||||
this.desiredPort = this.currentPort;
|
||||
};
|
||||
|
||||
@@ -92,8 +71,8 @@ export class PortForwardDialog extends Component<Props> {
|
||||
};
|
||||
|
||||
startPortForward = async () => {
|
||||
const { portForward } = this;
|
||||
const { currentPort, desiredPort, close } = this;
|
||||
const portForward = this.props.model.portForward;
|
||||
const { currentPort, desiredPort } = this;
|
||||
|
||||
try {
|
||||
// determine how many port-forwards are already active
|
||||
@@ -101,13 +80,13 @@ export class PortForwardDialog extends Component<Props> {
|
||||
|
||||
let port: number;
|
||||
|
||||
portForward.protocol = dialogState.useHttps ? "https" : "http";
|
||||
portForward.protocol = this.props.model.useHttps ? "https" : "http";
|
||||
|
||||
if (currentPort) {
|
||||
port = await modifyPortForward(portForward, desiredPort);
|
||||
port = await this.props.modifyPortForward(portForward, desiredPort);
|
||||
} else {
|
||||
portForward.forwardPort = desiredPort;
|
||||
port = await addPortForward(portForward);
|
||||
port = await this.props.addPortForward(portForward);
|
||||
|
||||
// if this is the first port-forward show the about notification
|
||||
if (!length) {
|
||||
@@ -115,7 +94,7 @@ export class PortForwardDialog extends Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
if (dialogState.openInBrowser) {
|
||||
if (this.props.model.openInBrowser) {
|
||||
portForward.forwardPort = port;
|
||||
openPortForward(portForward);
|
||||
}
|
||||
@@ -146,14 +125,14 @@ export class PortForwardDialog extends Component<Props> {
|
||||
<Checkbox
|
||||
data-testid="port-forward-https"
|
||||
label="https"
|
||||
value={dialogState.useHttps}
|
||||
onChange={value => dialogState.useHttps = value}
|
||||
value={this.props.model.useHttps}
|
||||
onChange={value => this.props.model.useHttps = value}
|
||||
/>
|
||||
<Checkbox
|
||||
data-testid="port-forward-open"
|
||||
label="Open in Browser"
|
||||
value={dialogState.openInBrowser}
|
||||
onChange={value => dialogState.openInBrowser = value}
|
||||
value={this.props.model.openInBrowser}
|
||||
onChange={value => this.props.model.openInBrowser = value}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
@@ -161,8 +140,8 @@ export class PortForwardDialog extends Component<Props> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, ...dialogProps } = this.props;
|
||||
const resourceName = this.portForward?.name ?? "";
|
||||
const { className, modifyPortForward, model, ...dialogProps } = this.props;
|
||||
const resourceName = this.props.model.portForward?.name ?? "";
|
||||
const header = (
|
||||
<h5>
|
||||
Port Forwarding for <span>{resourceName}</span>
|
||||
@@ -172,13 +151,13 @@ export class PortForwardDialog extends Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
isOpen={dialogState.isOpen}
|
||||
isOpen={this.props.model.isOpen}
|
||||
className={cssNames("PortForwardDialog", className)}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
close={this.close}
|
||||
close={this.props.model.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
<Wizard header={header} done={this.props.model.close}>
|
||||
<WizardStep
|
||||
contentClass="flex gaps column"
|
||||
next={this.startPortForward}
|
||||
@@ -191,3 +170,16 @@ export class PortForwardDialog extends Component<Props> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const PortForwardDialog = withInjectables<Dependencies, Props>(
|
||||
NonInjectedPortForwardDialog,
|
||||
|
||||
{
|
||||
getProps: (di, props) => ({
|
||||
modifyPortForward: di.inject(modifyPortForwardInjectable),
|
||||
addPortForward: di.inject(addPortForwardInjectable),
|
||||
model: di.inject(portForwardDialogModelInjectable),
|
||||
...props,
|
||||
}),
|
||||
},
|
||||
);
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import portForwardStoreInjectable from "../port-forward-store.injectable";
|
||||
|
||||
const addPortForwardInjectable = getInjectable({
|
||||
instantiate: (di) => di.inject(portForwardStoreInjectable).add,
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default addPortForwardInjectable;
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import portForwardStoreInjectable from "../port-forward-store.injectable";
|
||||
|
||||
const modifyPortForwardInjectable = getInjectable({
|
||||
instantiate: (di) => di.inject(portForwardStoreInjectable).modify,
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default modifyPortForwardInjectable;
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import { PortForwardStore } from "./port-forward-store";
|
||||
import type { ForwardedPort } from "../port-forward-item";
|
||||
import createStorageInjectable from "../../utils/create-storage/create-storage.injectable";
|
||||
|
||||
const portForwardStoreInjectable = getInjectable({
|
||||
instantiate: (di) => {
|
||||
const createStorage = di.inject(createStorageInjectable);
|
||||
|
||||
const storage = createStorage<ForwardedPort[] | undefined>(
|
||||
"port_forwards",
|
||||
undefined,
|
||||
);
|
||||
|
||||
return new PortForwardStore({ storage });
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default portForwardStoreInjectable;
|
||||
+67
-65
@@ -21,19 +21,21 @@
|
||||
|
||||
|
||||
import { 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 { apiBase } from "../api";
|
||||
import { ItemStore } from "../../../common/item.store";
|
||||
import { autoBind, disposer, getHostedClusterId, StorageHelper } from "../../utils";
|
||||
import { ForwardedPort, PortForwardItem } from "../port-forward-item";
|
||||
import { apiBase } from "../../api";
|
||||
import logger from "../../../common/logger";
|
||||
import { waitUntilFree } from "tcp-port-used";
|
||||
import logger from "../../common/logger";
|
||||
|
||||
interface Dependencies {
|
||||
storage: StorageHelper<ForwardedPort[] | undefined>
|
||||
}
|
||||
|
||||
export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||
private storage = createStorage<ForwardedPort[] | undefined>("port_forwards", undefined);
|
||||
|
||||
@observable portForwards: PortForwardItem[];
|
||||
|
||||
constructor() {
|
||||
constructor(private dependencies: Dependencies) {
|
||||
super();
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
@@ -42,13 +44,13 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||
}
|
||||
|
||||
private async init() {
|
||||
await this.storage.whenReady;
|
||||
await this.dependencies.storage.whenReady;
|
||||
|
||||
const savedPortForwards = this.storage.get(); // undefined on first load
|
||||
const savedPortForwards = this.dependencies.storage.get(); // undefined on first load
|
||||
|
||||
if (Array.isArray(savedPortForwards)) {
|
||||
logger.info("[PORT-FORWARD-STORE] starting saved port-forwards");
|
||||
await Promise.all(savedPortForwards.map(addPortForward));
|
||||
await Promise.all(savedPortForwards.map(this.add));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +64,7 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||
return this.loadItems(async () => {
|
||||
const portForwards = await getPortForwards(getHostedClusterId());
|
||||
|
||||
this.storage.set(portForwards);
|
||||
this.dependencies.storage.set(portForwards);
|
||||
|
||||
this.reset();
|
||||
portForwards.map(pf => this.portForwards.push(new PortForwardItem(pf)));
|
||||
@@ -71,12 +73,12 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||
});
|
||||
}
|
||||
|
||||
reset() {
|
||||
reset = () => {
|
||||
this.portForwards = [];
|
||||
}
|
||||
};
|
||||
|
||||
async removeSelectedItems() {
|
||||
return Promise.all(this.selectedItems.map(removePortForward));
|
||||
return Promise.all(this.selectedItems.map(this.remove));
|
||||
}
|
||||
|
||||
getById(id: string) {
|
||||
@@ -88,9 +90,58 @@ export class PortForwardStore extends ItemStore<PortForwardItem> {
|
||||
|
||||
return this.getItems()[index];
|
||||
}
|
||||
|
||||
add = async (portForward: ForwardedPort): Promise<number> => {
|
||||
const { port, forwardPort } = portForward;
|
||||
let response: PortForwardResult;
|
||||
|
||||
try {
|
||||
const protocol = portForward.protocol ?? "http";
|
||||
|
||||
response = await apiBase.post<PortForwardResult>(`/pods/port-forward/${portForward.namespace}/${portForward.kind}/${portForward.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}`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn("[PORT-FORWARD-STORE] Error adding port-forward:", error, portForward);
|
||||
throw (error);
|
||||
}
|
||||
|
||||
this.reset();
|
||||
|
||||
return response?.port;
|
||||
};
|
||||
|
||||
remove = async (portForward: ForwardedPort) => {
|
||||
const { port, forwardPort } = portForward;
|
||||
|
||||
try {
|
||||
await apiBase.del(`/pods/port-forward/${portForward.namespace}/${portForward.kind}/${portForward.name}`, { query: { port, forwardPort }});
|
||||
await waitUntilFree(+forwardPort, 200, 1000);
|
||||
} catch (error) {
|
||||
logger.warn("[PORT-FORWARD-STORE] Error removing port-forward:", error, portForward);
|
||||
throw (error);
|
||||
}
|
||||
|
||||
this.reset();
|
||||
};
|
||||
|
||||
modify = async (portForward: ForwardedPort, desiredPort: number): Promise<number> => {
|
||||
await this.remove(portForward);
|
||||
|
||||
portForward.forwardPort = desiredPort;
|
||||
|
||||
const port = await this.add(portForward);
|
||||
|
||||
this.reset();
|
||||
|
||||
return port;
|
||||
};
|
||||
}
|
||||
|
||||
interface PortForwardResult {
|
||||
export interface PortForwardResult {
|
||||
port: number;
|
||||
}
|
||||
|
||||
@@ -98,28 +149,6 @@ interface PortForwardsResult {
|
||||
portForwards: ForwardedPort[];
|
||||
}
|
||||
|
||||
export async function addPortForward(portForward: ForwardedPort): Promise<number> {
|
||||
const { port, forwardPort } = portForward;
|
||||
let response: PortForwardResult;
|
||||
|
||||
try {
|
||||
const protocol = portForward.protocol ?? "http";
|
||||
|
||||
response = await apiBase.post<PortForwardResult>(`/pods/port-forward/${portForward.namespace}/${portForward.kind}/${portForward.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}`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn("[PORT-FORWARD-STORE] Error adding port-forward:", error, portForward);
|
||||
throw (error);
|
||||
}
|
||||
portForwardStore.reset();
|
||||
|
||||
return response?.port;
|
||||
}
|
||||
|
||||
export async function getPortForward(portForward: ForwardedPort): Promise<number> {
|
||||
const { port, forwardPort, protocol } = portForward;
|
||||
let response: PortForwardResult;
|
||||
@@ -134,31 +163,6 @@ export async function getPortForward(portForward: ForwardedPort): Promise<number
|
||||
return response?.port;
|
||||
}
|
||||
|
||||
export async function modifyPortForward(portForward: ForwardedPort, desiredPort: number): Promise<number> {
|
||||
let port = 0;
|
||||
|
||||
await removePortForward(portForward);
|
||||
portForward.forwardPort = desiredPort;
|
||||
port = await addPortForward(portForward);
|
||||
|
||||
portForwardStore.reset();
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
export async function removePortForward(portForward: ForwardedPort) {
|
||||
const { port, forwardPort } = portForward;
|
||||
|
||||
try {
|
||||
await apiBase.del(`/pods/port-forward/${portForward.namespace}/${portForward.kind}/${portForward.name}`, { query: { port, forwardPort }});
|
||||
await waitUntilFree(+forwardPort, 200, 1000);
|
||||
} catch (error) {
|
||||
logger.warn("[PORT-FORWARD-STORE] Error removing port-forward:", error, portForward);
|
||||
throw (error);
|
||||
}
|
||||
portForwardStore.reset();
|
||||
}
|
||||
|
||||
export async function getPortForwards(clusterId?: string): Promise<ForwardedPort[]> {
|
||||
try {
|
||||
@@ -171,5 +175,3 @@ export async function getPortForwards(clusterId?: string): Promise<ForwardedPort
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export const portForwardStore = new PortForwardStore();
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
import portForwardStoreInjectable from "../port-forward-store.injectable";
|
||||
|
||||
const removePortForwardInjectable = getInjectable({
|
||||
instantiate: (di) => di.inject(portForwardStoreInjectable).remove,
|
||||
|
||||
lifecycle: lifecycleEnum.singleton,
|
||||
});
|
||||
|
||||
export default removePortForwardInjectable;
|
||||
Reference in new issue
Block a user