Move Cluster.apiUrl to seperate injectable (#7354)

* Refactor out Cluster.apiUrl to direct reading

- Should help prevent using stale data

- Removes some uses of synchronous FS operations

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Rename helper function to better communicate intent

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Improve prometheus handler tests to override less things

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton authored and GitHub committed 2023-03-31 15:28:14 -04:00
1 parent 18d660ea77
commit fe2fd4c1fd
53 files changed
+472 -640

No files matched your search

@@ -9,6 +9,7 @@ import type { Cluster } from "../../common/cluster/cluster";
import createKubeAuthProxyInjectable from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
import kubeAuthProxyCertificateInjectable from "../kube-auth-proxy/kube-auth-proxy-certificate.injectable";
import type { KubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
import clusterApiUrlInjectable from "../../features/cluster/connections/main/api-url.injectable";
export interface KubeAuthProxyServer {
getApiTarget(isLongRunningRequest?: boolean): Promise<ServerOptions>;
@@ -24,23 +25,23 @@ const thirtySecondsInMs = 30 * 1000;
const kubeAuthProxyServerInjectable = getInjectable({
id: "kube-auth-proxy-server",
instantiate: (di, cluster): KubeAuthProxyServer => {
const clusterUrl = new URL(cluster.apiUrl.get());
const createKubeAuthProxy = di.inject(createKubeAuthProxyInjectable);
const certificate = di.inject(kubeAuthProxyCertificateInjectable, clusterUrl.hostname);
const clusterApiUrl = di.inject(clusterApiUrlInjectable, cluster);
const createKubeAuthProxy = di.inject(createKubeAuthProxyInjectable, cluster);
let kubeAuthProxy: KubeAuthProxy | undefined = undefined;
let apiTarget: ServerOptions | undefined = undefined;
const ensureServerHelper = async (): Promise<KubeAuthProxy> => {
if (!kubeAuthProxy) {
const proxyEnv = Object.assign({}, process.env);
const proxyEnv = {
...process.env,
};
if (cluster.preferences.httpsProxy) {
proxyEnv.HTTPS_PROXY = cluster.preferences.httpsProxy;
}
kubeAuthProxy = createKubeAuthProxy(cluster, proxyEnv);
kubeAuthProxy = createKubeAuthProxy(proxyEnv);
}
await kubeAuthProxy.run();
@@ -49,31 +50,24 @@ const kubeAuthProxyServerInjectable = getInjectable({
};
const newApiTarget = async (timeout: number): Promise<ServerOptions> => {
const kubeAuthProxy = await ensureServerHelper();
const headers: Record<string, string> = {};
if (clusterUrl.hostname) {
headers.Host = clusterUrl.hostname;
// fix current IPv6 inconsistency in url.Parse() and httpProxy.
// with url.Parse the IPv6 Hostname has no Square brackets but httpProxy needs the Square brackets to work.
if (headers.Host.includes(":")) {
headers.Host = `[${headers.Host}]`;
}
}
const { hostname } = await clusterApiUrl();
const certificate = di.inject(kubeAuthProxyCertificateInjectable, hostname);
const { port, apiPrefix: path } = await ensureServerHelper();
return {
target: {
protocol: "https:",
host: "127.0.0.1",
port: kubeAuthProxy.port,
path: kubeAuthProxy.apiPrefix,
port,
path,
ca: certificate.cert,
},
changeOrigin: true,
timeout,
secure: true,
headers,
headers: {
Host: hostname,
},
};
};
+2 -17
View File
@@ -7,7 +7,6 @@ import "../../common/ipc/cluster";
import type { IComputedValue, IObservableValue, ObservableSet } from "mobx";
import { action, makeObservable, observe, reaction, toJS } from "mobx";
import type { Cluster } from "../../common/cluster/cluster";
import { isErrnoException } from "@k8slens/utilities";
import { isKubernetesCluster, KubernetesCluster, LensKubernetesClusterStatus } from "../../common/catalog-entities/kubernetes-cluster";
import { ipcMainOn } from "../../common/ipc";
import { once } from "lodash";
@@ -158,26 +157,12 @@ export class ClusterManager {
const cluster = this.dependencies.getClusterById(entity.getId());
if (!cluster) {
const model = {
this.dependencies.addCluster({
id: entity.getId(),
kubeConfigPath: entity.spec.kubeconfigPath,
contextName: entity.spec.kubeconfigContext,
accessibleNamespaces: entity.spec.accessibleNamespaces ?? [],
};
try {
/**
* Add the bare minimum of data to ClusterStore. And especially no
* preferences, as those might be configured by the entity's source
*/
this.dependencies.addCluster(model);
} catch (error) {
if (isErrnoException(error) && error.code === "ENOENT" && error.path === entity.spec.kubeconfigPath) {
this.dependencies.logger.warn(`${logPrefix} kubeconfig file disappeared`, model);
} else {
this.dependencies.logger.error(`${logPrefix} failed to add cluster: ${error}`, model);
}
}
});
} else {
cluster.kubeConfigPath.set(entity.spec.kubeconfigPath);
cluster.contextName.set(entity.spec.kubeconfigContext);
@@ -34,8 +34,6 @@ describe("update-entity-metadata", () => {
id: "some-id",
contextName: "some-context",
kubeConfigPath: "minikube-config.yml",
}, {
clusterServerUrl: "foo",
});
detectedMetadata = {
@@ -31,8 +31,6 @@ describe("update-entity-spec", () => {
id: "some-id",
contextName: "some-context",
kubeConfigPath: "minikube-config.yml",
}, {
clusterServerUrl: "foo",
});
entity = new KubernetesCluster({