mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Restructure to monorepo (#6907)
* wip: restructure to monorepo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor create-release-pr to a package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * github workflow fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix typo Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * add webpack-env types to core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix github workflows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * refactor/fix integration tests Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * lint fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * yarn run dev Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * eslint settings for vscode Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * move templates to right package Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * open-lens build fixes Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * integration test fix Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix nx task dependencies Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * use bash shell for unit tests in test workflow Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix test:unit for windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix win-ca webpack error in open-lens Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix build:app on windows Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove ELECTRON_BUILDER_EXTRA_ARGS Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * sync src/ from master Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * remove Makefile from core Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0066ca4ea2
commit
2657df2293
3321 files changed
+28699
-11447
No files matched your search
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { KubeAuthProxyDependencies } from "./kube-auth-proxy";
|
||||
import { KubeAuthProxy } from "./kube-auth-proxy";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import spawnInjectable from "../child-process/spawn.injectable";
|
||||
import kubeAuthProxyCertificateInjectable from "./kube-auth-proxy-certificate.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import waitUntilPortIsUsedInjectable from "./wait-until-port-is-used/wait-until-port-is-used.injectable";
|
||||
import lensK8sProxyPathInjectable from "./lens-k8s-proxy-path.injectable";
|
||||
import getPortFromStreamInjectable from "../utils/get-port-from-stream.injectable";
|
||||
|
||||
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
|
||||
|
||||
const createKubeAuthProxyInjectable = getInjectable({
|
||||
id: "create-kube-auth-proxy",
|
||||
|
||||
instantiate: (di): CreateKubeAuthProxy => {
|
||||
const dependencies: Omit<KubeAuthProxyDependencies, "proxyCert"> = {
|
||||
proxyBinPath: di.inject(lensK8sProxyPathInjectable),
|
||||
spawn: di.inject(spawnInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
waitUntilPortIsUsed: di.inject(waitUntilPortIsUsedInjectable),
|
||||
getPortFromStream: di.inject(getPortFromStreamInjectable),
|
||||
};
|
||||
|
||||
return (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => {
|
||||
const clusterUrl = new URL(cluster.apiUrl);
|
||||
|
||||
return new KubeAuthProxy({
|
||||
...dependencies,
|
||||
proxyCert: di.inject(kubeAuthProxyCertificateInjectable, clusterUrl.hostname),
|
||||
}, cluster, environmentVariables);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default createKubeAuthProxyInjectable;
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { generate } from "selfsigned";
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
|
||||
const kubeAuthProxyCertificateInjectable = getInjectable({
|
||||
id: "kube-auth-proxy-certificate",
|
||||
instantiate: (di, hostname) => generate(
|
||||
[
|
||||
{ name: "commonName", value: "Lens Certificate Authority" },
|
||||
{ name: "organizationName", value: "Lens" },
|
||||
],
|
||||
{
|
||||
keySize: 2048,
|
||||
algorithm: "sha256",
|
||||
days: 365,
|
||||
extensions: [
|
||||
{ name: "basicConstraints", cA: true },
|
||||
{
|
||||
name: "subjectAltName", altNames: [
|
||||
{ type: 2, value: hostname },
|
||||
{ type: 2, value: "localhost" },
|
||||
{ type: 7, ip: "127.0.0.1" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
lifecycle: lifecycleEnum.keyedSingleton({
|
||||
getInstanceKey: (di, hostname: string) => hostname,
|
||||
}),
|
||||
});
|
||||
|
||||
export default kubeAuthProxyCertificateInjectable;
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { ChildProcess } from "child_process";
|
||||
import { randomBytes } from "crypto";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import type { GetPortFromStream } from "../utils/get-port-from-stream.injectable";
|
||||
import { makeObservable, observable, when } from "mobx";
|
||||
import type { SelfSignedCert } from "selfsigned";
|
||||
import assert from "assert";
|
||||
import { TypedRegEx } from "typed-regex";
|
||||
import type { Spawn } from "../child-process/spawn.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { WaitUntilPortIsUsed } from "./wait-until-port-is-used/wait-until-port-is-used.injectable";
|
||||
|
||||
const startingServeMatcher = "starting to serve on (?<address>.+)";
|
||||
const startingServeRegex = Object.assign(TypedRegEx(startingServeMatcher, "i"), {
|
||||
rawMatcher: startingServeMatcher,
|
||||
});
|
||||
|
||||
export interface KubeAuthProxyDependencies {
|
||||
readonly proxyBinPath: string;
|
||||
readonly proxyCert: SelfSignedCert;
|
||||
readonly logger: Logger;
|
||||
spawn: Spawn;
|
||||
waitUntilPortIsUsed: WaitUntilPortIsUsed;
|
||||
getPortFromStream: GetPortFromStream;
|
||||
}
|
||||
|
||||
export class KubeAuthProxy {
|
||||
public readonly apiPrefix = `/${randomBytes(8).toString("hex")}`;
|
||||
|
||||
public get port(): number {
|
||||
const port = this._port;
|
||||
|
||||
assert(port, "port has not yet been initialized");
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
protected _port?: number;
|
||||
protected proxyProcess?: ChildProcess;
|
||||
@observable protected ready = false;
|
||||
|
||||
constructor(private readonly dependencies: KubeAuthProxyDependencies, protected readonly cluster: Cluster, protected readonly env: NodeJS.ProcessEnv) {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get whenReady() {
|
||||
return when(() => this.ready);
|
||||
}
|
||||
|
||||
public async run(): Promise<void> {
|
||||
if (this.proxyProcess) {
|
||||
return this.whenReady;
|
||||
}
|
||||
|
||||
const proxyBin = this.dependencies.proxyBinPath;
|
||||
const cert = this.dependencies.proxyCert;
|
||||
|
||||
this.proxyProcess = this.dependencies.spawn(proxyBin, [], {
|
||||
env: {
|
||||
...this.env,
|
||||
KUBECONFIG: this.cluster.kubeConfigPath,
|
||||
KUBECONFIG_CONTEXT: this.cluster.contextName,
|
||||
API_PREFIX: this.apiPrefix,
|
||||
PROXY_KEY: cert.private,
|
||||
PROXY_CERT: cert.cert,
|
||||
},
|
||||
});
|
||||
this.proxyProcess.on("error", (error) => {
|
||||
this.cluster.broadcastConnectUpdate(error.message, true);
|
||||
this.exit();
|
||||
});
|
||||
|
||||
this.proxyProcess.on("exit", (code) => {
|
||||
this.cluster.broadcastConnectUpdate(`proxy exited with code: ${code}`, code ? code > 0: false);
|
||||
this.exit();
|
||||
});
|
||||
|
||||
this.proxyProcess.on("disconnect", () => {
|
||||
this.cluster.broadcastConnectUpdate("Proxy disconnected communications", true );
|
||||
this.exit();
|
||||
});
|
||||
|
||||
assert(this.proxyProcess.stderr);
|
||||
assert(this.proxyProcess.stdout);
|
||||
|
||||
this.proxyProcess.stderr.on("data", (data: Buffer) => {
|
||||
if (data.includes("http: TLS handshake error")) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cluster.broadcastConnectUpdate(data.toString(), true);
|
||||
});
|
||||
|
||||
this.proxyProcess.stdout.on("data", (data: Buffer) => {
|
||||
if (typeof this._port === "number") {
|
||||
this.cluster.broadcastConnectUpdate(data.toString());
|
||||
}
|
||||
});
|
||||
|
||||
this._port = await this.dependencies.getPortFromStream(this.proxyProcess.stdout, {
|
||||
lineRegex: startingServeRegex,
|
||||
onFind: () => this.cluster.broadcastConnectUpdate("Authentication proxy started"),
|
||||
});
|
||||
|
||||
this.dependencies.logger.info(`[KUBE-AUTH-PROXY]: found port=${this._port}`);
|
||||
|
||||
try {
|
||||
await this.dependencies.waitUntilPortIsUsed(this.port, 500, 10000);
|
||||
this.ready = true;
|
||||
} catch (error) {
|
||||
this.dependencies.logger.warn("[KUBE-AUTH-PROXY]: waitUntilUsed failed", error);
|
||||
this.cluster.broadcastConnectUpdate("Proxy port failed to be used within timelimit, restarting...", true);
|
||||
this.exit();
|
||||
|
||||
return this.run();
|
||||
}
|
||||
}
|
||||
|
||||
public exit() {
|
||||
this.ready = false;
|
||||
|
||||
if (this.proxyProcess) {
|
||||
this.dependencies.logger.debug("[KUBE-AUTH]: stopping local proxy", this.cluster.getMeta());
|
||||
this.proxyProcess.removeAllListeners();
|
||||
this.proxyProcess.stderr?.removeAllListeners();
|
||||
this.proxyProcess.stdout?.removeAllListeners();
|
||||
this.proxyProcess.kill();
|
||||
this.proxyProcess = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import bundledBinaryPathInjectable from "../../common/utils/bundled-binary-path.injectable";
|
||||
|
||||
const lensK8sProxyPathInjectable = getInjectable({
|
||||
id: "lens-k8s-proxy-path",
|
||||
instantiate: (di) => di.inject(bundledBinaryPathInjectable, "lens-k8s-proxy"),
|
||||
});
|
||||
|
||||
export default lensK8sProxyPathInjectable;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getGlobalOverride } from "../../../common/test-utils/get-global-override";
|
||||
import waitUntilPortIsUsedInjectable from "./wait-until-port-is-used.injectable";
|
||||
|
||||
export default getGlobalOverride(
|
||||
waitUntilPortIsUsedInjectable,
|
||||
() => () => {
|
||||
throw new Error(
|
||||
"Tried to wait until port is used without explicit override.",
|
||||
);
|
||||
},
|
||||
);
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { waitUntilUsed } from "tcp-port-used";
|
||||
|
||||
export type WaitUntilPortIsUsed = (
|
||||
port: number,
|
||||
retryAfterMs: number,
|
||||
timeoutAfterMs: number
|
||||
) => Promise<void>;
|
||||
|
||||
const waitUntilPortIsUsedInjectable = getInjectable({
|
||||
id: "wait-until-port-is-used",
|
||||
instantiate: (): WaitUntilPortIsUsed => waitUntilUsed,
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default waitUntilPortIsUsedInjectable;
|
||||
Reference in new issue
Block a user