mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Support window nodes for node-shells (#3624)
* Support window nodes for node-shells Signed-off-by: Sebastian Malton <sebastian@malton.name> * Also check beta.kubernetes/os label Signed-off-by: Sebastian Malton <sebastian@malton.name> * Add comment about linux fallback Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
c09a57370e
commit
5eb1b8553d
@ -236,13 +236,10 @@ export class Node extends KubeObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getOperatingSystem(): string {
|
getOperatingSystem(): string {
|
||||||
const label = this.getLabels().find(label => label.startsWith("kubernetes.io/os="));
|
return this.metadata?.labels?.["kubernetes.io/os"]
|
||||||
|
|| this.metadata?.labels?.["beta.kubernetes.io/os"]
|
||||||
if (label) {
|
|| this.status?.nodeInfo?.operatingSystem
|
||||||
return label.split("=", 2)[1];
|
|| "linux";
|
||||||
}
|
|
||||||
|
|
||||||
return "linux";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isUnschedulable() {
|
isUnschedulable() {
|
||||||
|
|||||||
@ -224,10 +224,7 @@ export class KubeApi<T extends KubeObject> {
|
|||||||
isNamespaced = options.objectConstructor?.namespaced,
|
isNamespaced = options.objectConstructor?.namespaced,
|
||||||
} = options || {};
|
} = options || {};
|
||||||
|
|
||||||
if (!options.apiBase) {
|
const { apiBase, apiPrefix, apiGroup, apiVersion, resource } = parseKubeApi(options.apiBase || objectConstructor.apiBase);
|
||||||
options.apiBase = objectConstructor.apiBase;
|
|
||||||
}
|
|
||||||
const { apiBase, apiPrefix, apiGroup, apiVersion, resource } = parseKubeApi(options.apiBase);
|
|
||||||
|
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.isNamespaced = isNamespaced;
|
this.isNamespaced = isNamespaced;
|
||||||
|
|||||||
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
import { JsonApi, JsonApiData, JsonApiError } from "./json-api";
|
import { JsonApi, JsonApiData, JsonApiError } from "./json-api";
|
||||||
import type { Response } from "node-fetch";
|
import type { Response } from "node-fetch";
|
||||||
|
import type { Cluster } from "../../main/cluster";
|
||||||
|
import { LensProxy } from "../../main/lens-proxy";
|
||||||
|
import { apiKubePrefix, isDebugging } from "../vars";
|
||||||
|
|
||||||
export interface KubeJsonApiListMetadata {
|
export interface KubeJsonApiListMetadata {
|
||||||
resourceVersion: string;
|
resourceVersion: string;
|
||||||
@ -70,6 +73,20 @@ export interface KubeJsonApiError extends JsonApiError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class KubeJsonApi extends JsonApi<KubeJsonApiData> {
|
export class KubeJsonApi extends JsonApi<KubeJsonApiData> {
|
||||||
|
static forCluster(cluster: Cluster): KubeJsonApi {
|
||||||
|
const port = LensProxy.getInstance().port;
|
||||||
|
|
||||||
|
return new this({
|
||||||
|
serverAddress: `http://127.0.0.1:${port}`,
|
||||||
|
apiBase: apiKubePrefix,
|
||||||
|
debug: isDebugging,
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
"Host": `${cluster.id}.localhost:${port}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected parseError(error: KubeJsonApiError | any, res: Response): string[] {
|
protected parseError(error: KubeJsonApiError | any, res: Response): string[] {
|
||||||
const { status, reason, message } = error;
|
const { status, reason, message } = error;
|
||||||
|
|
||||||
@ -80,4 +97,3 @@ export class KubeJsonApi extends JsonApi<KubeJsonApiData> {
|
|||||||
return super.parseError(error, res);
|
return super.parseError(error, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -240,27 +240,20 @@ export class ClusterManager extends Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getClusterForRequest(req: http.IncomingMessage): Cluster {
|
getClusterForRequest(req: http.IncomingMessage): Cluster {
|
||||||
let cluster: Cluster = null;
|
|
||||||
|
|
||||||
// lens-server is connecting to 127.0.0.1:<port>/<uid>
|
// lens-server is connecting to 127.0.0.1:<port>/<uid>
|
||||||
if (req.headers.host.startsWith("127.0.0.1")) {
|
if (req.headers.host.startsWith("127.0.0.1")) {
|
||||||
const clusterId = req.url.split("/")[1];
|
const clusterId = req.url.split("/")[1];
|
||||||
|
const cluster = this.store.getById(clusterId);
|
||||||
cluster = this.store.getById(clusterId);
|
|
||||||
|
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
// we need to swap path prefix so that request is proxied to kube api
|
// we need to swap path prefix so that request is proxied to kube api
|
||||||
req.url = req.url.replace(`/${clusterId}`, apiKubePrefix);
|
req.url = req.url.replace(`/${clusterId}`, apiKubePrefix);
|
||||||
}
|
}
|
||||||
} else if (req.headers["x-cluster-id"]) {
|
|
||||||
cluster = this.store.getById(req.headers["x-cluster-id"].toString());
|
|
||||||
} else {
|
|
||||||
const clusterId = getClusterIdFromHost(req.headers.host);
|
|
||||||
|
|
||||||
cluster = this.store.getById(clusterId);
|
return cluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cluster;
|
return this.store.getById(getClusterIdFromHost(req.headers.host));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,9 @@ import type { KubeConfig } from "@kubernetes/client-node";
|
|||||||
import type { Cluster } from "../cluster";
|
import type { Cluster } from "../cluster";
|
||||||
import { ShellOpenError, ShellSession } from "./shell-session";
|
import { ShellOpenError, ShellSession } from "./shell-session";
|
||||||
import { get } from "lodash";
|
import { get } from "lodash";
|
||||||
|
import { Node, NodesApi } from "../../common/k8s-api/endpoints";
|
||||||
|
import { KubeJsonApi } from "../../common/k8s-api/kube-json-api";
|
||||||
|
import logger from "../logger";
|
||||||
|
|
||||||
export class NodeShellSession extends ShellSession {
|
export class NodeShellSession extends ShellSession {
|
||||||
ShellType = "node-shell";
|
ShellType = "node-shell";
|
||||||
@ -55,10 +58,27 @@ export class NodeShellSession extends ShellSession {
|
|||||||
throw new ShellOpenError("failed to create node pod", error);
|
throw new ShellOpenError("failed to create node pod", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = ["exec", "-i", "-t", "-n", "kube-system", this.podId, "--", "sh", "-c", "((clear && bash) || (clear && ash) || (clear && sh))"];
|
|
||||||
const env = await this.getCachedShellEnv();
|
const env = await this.getCachedShellEnv();
|
||||||
|
const args = ["exec", "-i", "-t", "-n", "kube-system", this.podId, "--"];
|
||||||
|
const nodeApi = new NodesApi({
|
||||||
|
objectConstructor: Node,
|
||||||
|
request: KubeJsonApi.forCluster(this.cluster),
|
||||||
|
});
|
||||||
|
const node = await nodeApi.get({ name: this.nodeName });
|
||||||
|
const nodeOs = node.getOperatingSystem();
|
||||||
|
|
||||||
await super.open(shell, args, env);
|
switch (nodeOs) {
|
||||||
|
default:
|
||||||
|
logger.warn(`[NODE-SHELL-SESSION]: could not determine node OS, falling back with assumption of linux`);
|
||||||
|
case "linux":
|
||||||
|
args.push("sh", "-c", "((clear && bash) || (clear && ash) || (clear && sh))");
|
||||||
|
break;
|
||||||
|
case "windows":
|
||||||
|
args.push("powershell");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.open(shell, args, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createNodeShellPod() {
|
protected createNodeShellPod() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user