mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Cleanup 'Cluster' to remove environment specific details (#6951)
- requestNamespaceListPermissions is infallable so no need to have the extra try/catch - Refactor isMetricHidden method away from Cluster - Refactor shouldShowResource out of Cluster - Refactor isInLocalKubeconfig out of Cluster - Remove depecrated and unused workspace from Cluster - Refactor out kubectl as a dependency of Cluster - Remove from cluster getter used only once - Split out ClusterConnection from Cluster - Also split out KubeAuthProxyServer from ContextHandler - Rename ContextHandler to PrometheusHandler - Cleanup onNetworkOffline/Online impls within ClusterManager - Remove annotations from ClusterConnection - Remove mobx annotations from Cluster - Rename loadConfigFromFileInjectable - Remove all uses of dead createClusterInjectionToken - Fix type errors related to broadcastConnectionUpdate Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
e6d6d1d8f7
commit
ad9bafe2a5
133 files changed
+2544
-1961
No files matched your search
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { LensProxy } from "./lens-proxy";
|
||||
import { kubeApiUpgradeRequest } from "./proxy-functions";
|
||||
import routerInjectable from "../router/router.injectable";
|
||||
import httpProxy from "http-proxy";
|
||||
import shellApiRequestInjectable from "./proxy-functions/shell-api-request.injectable";
|
||||
@@ -14,6 +13,8 @@ import emitAppEventInjectable from "../../common/app-event-bus/emit-event.inject
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import lensProxyCertificateInjectable from "../../common/certificate/lens-proxy-certificate.injectable";
|
||||
import getClusterForRequestInjectable from "./get-cluster-for-request.injectable";
|
||||
import kubeAuthProxyServerInjectable from "../cluster/kube-auth-proxy-server.injectable";
|
||||
import kubeApiUpgradeRequestInjectable from "./proxy-functions/kube-api-upgrade-request.injectable";
|
||||
|
||||
const lensProxyInjectable = getInjectable({
|
||||
id: "lens-proxy",
|
||||
@@ -21,7 +22,7 @@ const lensProxyInjectable = getInjectable({
|
||||
instantiate: (di) => new LensProxy({
|
||||
router: di.inject(routerInjectable),
|
||||
proxy: httpProxy.createProxy(),
|
||||
kubeApiUpgradeRequest,
|
||||
kubeApiUpgradeRequest: di.inject(kubeApiUpgradeRequestInjectable),
|
||||
shellApiRequest: di.inject(shellApiRequestInjectable),
|
||||
getClusterForRequest: di.inject(getClusterForRequestInjectable),
|
||||
lensProxyPort: di.inject(lensProxyPortInjectable),
|
||||
@@ -29,6 +30,7 @@ const lensProxyInjectable = getInjectable({
|
||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
certificate: di.inject(lensProxyCertificateInjectable).get(),
|
||||
getKubeAuthProxyServer: (cluster) => di.inject(kubeAuthProxyServerInjectable, cluster),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import type http from "http";
|
||||
import type httpProxy from "http-proxy";
|
||||
import { apiPrefix, apiKubePrefix } from "../../common/vars";
|
||||
import type { Router } from "../router/router";
|
||||
import type { ClusterContextHandler } from "../context-handler/context-handler";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import type { ProxyApiRequestArgs } from "./proxy-functions";
|
||||
import { getBoolean } from "../utils/parse-query";
|
||||
@@ -18,6 +17,7 @@ import type { SetRequired } from "type-fest";
|
||||
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { SelfSignedCert } from "selfsigned";
|
||||
import type { KubeAuthProxyServer } from "../cluster/kube-auth-proxy-server.injectable";
|
||||
|
||||
export type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
|
||||
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
|
||||
@@ -28,6 +28,7 @@ interface Dependencies {
|
||||
shellApiRequest: LensProxyApiRequest;
|
||||
kubeApiUpgradeRequest: LensProxyApiRequest;
|
||||
emitAppEvent: EmitAppEvent;
|
||||
getKubeAuthProxyServer: (cluster: Cluster) => KubeAuthProxyServer;
|
||||
readonly router: Router;
|
||||
readonly proxy: httpProxy;
|
||||
readonly lensProxyPort: { set: (portNumber: number) => void };
|
||||
@@ -220,15 +221,6 @@ export class LensProxy {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
protected async getProxyTarget(req: http.IncomingMessage, contextHandler: ClusterContextHandler): Promise<httpProxy.ServerOptions | void> {
|
||||
if (req.url?.startsWith(apiKubePrefix)) {
|
||||
delete req.headers.authorization;
|
||||
req.url = req.url.replace(apiKubePrefix, "");
|
||||
|
||||
return contextHandler.getApiTarget(isLongRunningRequest(req.url));
|
||||
}
|
||||
}
|
||||
|
||||
protected getRequestId(req: http.IncomingMessage): string {
|
||||
assert(req.headers.host);
|
||||
|
||||
@@ -238,8 +230,12 @@ export class LensProxy {
|
||||
protected async handleRequest(req: ServerIncomingMessage, res: http.ServerResponse) {
|
||||
const cluster = this.dependencies.getClusterForRequest(req);
|
||||
|
||||
if (cluster) {
|
||||
const proxyTarget = await this.getProxyTarget(req, cluster.contextHandler);
|
||||
if (cluster && req.url.startsWith(apiKubePrefix)) {
|
||||
delete req.headers.authorization;
|
||||
req.url = req.url.replace(apiKubePrefix, "");
|
||||
|
||||
const kubeAuthProxyServer = this.dependencies.getKubeAuthProxyServer(cluster);
|
||||
const proxyTarget = await kubeAuthProxyServer.getApiTarget(isLongRunningRequest(req.url));
|
||||
|
||||
if (proxyTarget) {
|
||||
return this.dependencies.proxy.web(req, res, proxyTarget);
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
export * from "./kube-api-upgrade-request";
|
||||
export * from "./types";
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { chunk } from "lodash";
|
||||
import type { ConnectionOptions } from "tls";
|
||||
import { connect } from "tls";
|
||||
import url, { URL } from "url";
|
||||
import { apiKubePrefix } from "../../../common/vars";
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { LensProxyApiRequest } from "../lens-proxy";
|
||||
import kubeAuthProxyServerInjectable from "../../cluster/kube-auth-proxy-server.injectable";
|
||||
import kubeAuthProxyCertificateInjectable from "../../kube-auth-proxy/kube-auth-proxy-certificate.injectable";
|
||||
|
||||
const skipRawHeaders = new Set(["Host", "Authorization"]);
|
||||
|
||||
const kubeApiUpgradeRequestInjectable = getInjectable({
|
||||
id: "kube-api-upgrade-request",
|
||||
instantiate: (di): LensProxyApiRequest => async ({ req, socket, head, cluster }) => {
|
||||
const clusterUrl = new URL(cluster.apiUrl.get());
|
||||
const kubeAuthProxyServer = di.inject(kubeAuthProxyServerInjectable, cluster);
|
||||
const kubeAuthProxyCertificate = di.inject(kubeAuthProxyCertificateInjectable, clusterUrl.hostname);
|
||||
|
||||
const proxyUrl = await kubeAuthProxyServer.ensureAuthProxyUrl() + req.url.replace(apiKubePrefix, "");
|
||||
const apiUrl = url.parse(cluster.apiUrl.get());
|
||||
const pUrl = url.parse(proxyUrl);
|
||||
const connectOpts: ConnectionOptions = {
|
||||
port: pUrl.port ? parseInt(pUrl.port) : undefined,
|
||||
host: pUrl.hostname ?? undefined,
|
||||
ca: kubeAuthProxyCertificate.cert,
|
||||
};
|
||||
|
||||
const proxySocket = connect(connectOpts, () => {
|
||||
proxySocket.write(`${req.method} ${pUrl.path} HTTP/1.1\r\n`);
|
||||
proxySocket.write(`Host: ${apiUrl.host}\r\n`);
|
||||
|
||||
for (const [key, value] of chunk(req.rawHeaders, 2)) {
|
||||
if (skipRawHeaders.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
proxySocket.write(`${key}: ${value}\r\n`);
|
||||
}
|
||||
|
||||
proxySocket.write("\r\n");
|
||||
proxySocket.write(head);
|
||||
});
|
||||
|
||||
proxySocket.setKeepAlive(true);
|
||||
socket.setKeepAlive(true);
|
||||
proxySocket.setTimeout(0);
|
||||
socket.setTimeout(0);
|
||||
|
||||
proxySocket.on("data", function (chunk) {
|
||||
socket.write(chunk);
|
||||
});
|
||||
proxySocket.on("end", function () {
|
||||
socket.end();
|
||||
});
|
||||
proxySocket.on("error", function () {
|
||||
socket.write(`HTTP/${req.httpVersion} 500 Connection error\r\n\r\n`);
|
||||
socket.end();
|
||||
});
|
||||
socket.on("data", function (chunk) {
|
||||
proxySocket.write(chunk);
|
||||
});
|
||||
socket.on("end", function () {
|
||||
proxySocket.end();
|
||||
});
|
||||
socket.on("error", function () {
|
||||
proxySocket.end();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default kubeApiUpgradeRequestInjectable;
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { chunk } from "lodash";
|
||||
import type { ConnectionOptions } from "tls";
|
||||
import { connect } from "tls";
|
||||
import url from "url";
|
||||
import { apiKubePrefix } from "../../../common/vars";
|
||||
import type { ProxyApiRequestArgs } from "./types";
|
||||
|
||||
const skipRawHeaders = new Set(["Host", "Authorization"]);
|
||||
|
||||
export async function kubeApiUpgradeRequest({ req, socket, head, cluster }: ProxyApiRequestArgs) {
|
||||
const proxyUrl = await cluster.contextHandler.resolveAuthProxyUrl() + req.url.replace(apiKubePrefix, "");
|
||||
const proxyCa = cluster.contextHandler.resolveAuthProxyCa();
|
||||
const apiUrl = url.parse(cluster.apiUrl);
|
||||
const pUrl = url.parse(proxyUrl);
|
||||
const connectOpts: ConnectionOptions = {
|
||||
port: pUrl.port ? parseInt(pUrl.port) : undefined,
|
||||
host: pUrl.hostname ?? undefined,
|
||||
ca: proxyCa,
|
||||
};
|
||||
|
||||
const proxySocket = connect(connectOpts, () => {
|
||||
proxySocket.write(`${req.method} ${pUrl.path} HTTP/1.1\r\n`);
|
||||
proxySocket.write(`Host: ${apiUrl.host}\r\n`);
|
||||
|
||||
for (const [key, value] of chunk(req.rawHeaders, 2)) {
|
||||
if (skipRawHeaders.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
proxySocket.write(`${key}: ${value}\r\n`);
|
||||
}
|
||||
|
||||
proxySocket.write("\r\n");
|
||||
proxySocket.write(head);
|
||||
});
|
||||
|
||||
proxySocket.setKeepAlive(true);
|
||||
socket.setKeepAlive(true);
|
||||
proxySocket.setTimeout(0);
|
||||
socket.setTimeout(0);
|
||||
|
||||
proxySocket.on("data", function (chunk) {
|
||||
socket.write(chunk);
|
||||
});
|
||||
proxySocket.on("end", function () {
|
||||
socket.end();
|
||||
});
|
||||
proxySocket.on("error", function () {
|
||||
socket.write(`HTTP/${req.httpVersion} 500 Connection error\r\n\r\n`);
|
||||
socket.end();
|
||||
});
|
||||
socket.on("data", function (chunk) {
|
||||
proxySocket.write(chunk);
|
||||
});
|
||||
socket.on("end", function () {
|
||||
proxySocket.end();
|
||||
});
|
||||
socket.on("error", function () {
|
||||
proxySocket.end();
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user