mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix changing to got
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
0b98f59f59
commit
07b75b8027
@ -234,8 +234,6 @@
|
||||
"react-dom": "^17.0.1",
|
||||
"react-router": "^5.2.0",
|
||||
"readable-stream": "^3.6.0",
|
||||
"request": "^2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"semver": "^7.3.2",
|
||||
"serializr": "^2.0.3",
|
||||
"shell-env": "^3.0.1",
|
||||
@ -291,8 +289,6 @@
|
||||
"@types/react-select": "^3.0.13",
|
||||
"@types/react-window": "^1.8.2",
|
||||
"@types/readable-stream": "^2.3.9",
|
||||
"@types/request": "^2.48.5",
|
||||
"@types/request-promise-native": "^1.0.17",
|
||||
"@types/semver": "^7.2.0",
|
||||
"@types/sharp": "^0.26.0",
|
||||
"@types/shelljs": "^0.8.8",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import requestPromise from "request-promise-native";
|
||||
import got from "got/dist/source";
|
||||
import packageInfo from "../../../package.json";
|
||||
|
||||
export function getAppVersion(): string {
|
||||
@ -14,11 +14,7 @@ export function getBundledExtensions(): string[] {
|
||||
}
|
||||
|
||||
export async function getAppVersionFromProxyServer(proxyPort: number): Promise<string> {
|
||||
const response = await requestPromise({
|
||||
method: "GET",
|
||||
uri: `http://localhost:${proxyPort}/version`,
|
||||
resolveWithFullResponse: true
|
||||
});
|
||||
const responseJson = await got(`http://localhost:${proxyPort}/version`).json<any>();
|
||||
|
||||
return JSON.parse(response.body).version;
|
||||
return responseJson.version;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import request from "request";
|
||||
import got, { CancelableRequest } from "got";
|
||||
|
||||
export interface DownloadFileOptions {
|
||||
url: string;
|
||||
@ -6,32 +6,6 @@ export interface DownloadFileOptions {
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
export interface DownloadFileTicket {
|
||||
url: string;
|
||||
promise: Promise<Buffer>;
|
||||
cancel(): void;
|
||||
}
|
||||
|
||||
export function downloadFile({ url, timeout, gzip = true }: DownloadFileOptions): DownloadFileTicket {
|
||||
const fileChunks: Buffer[] = [];
|
||||
const req = request(url, { gzip, timeout });
|
||||
const promise: Promise<Buffer> = new Promise((resolve, reject) => {
|
||||
req.on("data", (chunk: Buffer) => {
|
||||
fileChunks.push(chunk);
|
||||
});
|
||||
req.once("error", err => {
|
||||
reject({ url, err });
|
||||
});
|
||||
req.once("complete", () => {
|
||||
resolve(Buffer.concat(fileChunks));
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
url,
|
||||
promise,
|
||||
cancel() {
|
||||
req.abort();
|
||||
}
|
||||
};
|
||||
export function downloadFile({ url, timeout, gzip = true }: DownloadFileOptions): CancelableRequest<Buffer> {
|
||||
return got(url, { timeout, decompress: gzip }).buffer();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import request, { RequestPromiseOptions } from "request-promise-native";
|
||||
import { Cluster } from "../cluster";
|
||||
import { OptionsOfJSONResponseBody, Response } from "got";
|
||||
import { Cluster, k8sRequest } from "../cluster";
|
||||
|
||||
export type ClusterDetectionResult = {
|
||||
value: string | number | boolean
|
||||
@ -18,17 +18,10 @@ export class BaseClusterDetector {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected async k8sRequest<T = any>(path: string, options: RequestPromiseOptions = {}): Promise<T> {
|
||||
const apiUrl = this.cluster.kubeProxyUrl + path;
|
||||
protected async k8sRequest<T>(path: string, options: OptionsOfJSONResponseBody = {}): Promise<[Response<T>, T]> {
|
||||
options.headers ??= {};
|
||||
options.headers["Host"] ??= `${this.cluster.id}.${this.cluster.kubeProxyUrl.host}`; // required in ClusterManager.getClusterForRequest()''
|
||||
|
||||
return request(apiUrl, {
|
||||
json: true,
|
||||
timeout: 30000,
|
||||
...options,
|
||||
headers: {
|
||||
Host: `${this.cluster.id}.${this.cluster.kubeProxyUrl.host}`, // required in ClusterManager.getClusterForRequest()
|
||||
...(options.headers || {}),
|
||||
},
|
||||
});
|
||||
return k8sRequest(this.cluster.getUrlTo(path), options);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,8 +19,8 @@ export class ClusterIdDetector extends BaseClusterDetector {
|
||||
}
|
||||
|
||||
protected async getDefaultNamespaceId() {
|
||||
const response = await this.k8sRequest("/api/v1/namespaces/default");
|
||||
const [, responseJson] = await this.k8sRequest<any>("/api/v1/namespaces/default");
|
||||
|
||||
return response.metadata.uid;
|
||||
return responseJson.metadata.uid;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ export class DistributionDetector extends BaseClusterDetector {
|
||||
if (this.isK0s()) {
|
||||
return { value: "k0s", accuracy: 80};
|
||||
}
|
||||
|
||||
|
||||
if (this.isVMWare()) {
|
||||
return { value: "vmware", accuracy: 90};
|
||||
}
|
||||
@ -90,9 +90,9 @@ export class DistributionDetector extends BaseClusterDetector {
|
||||
public async getKubernetesVersion() {
|
||||
if (this.cluster.version) return this.cluster.version;
|
||||
|
||||
const response = await this.k8sRequest("/version");
|
||||
const [,responseJson] = await this.k8sRequest<any>("/version");
|
||||
|
||||
return response.gitVersion;
|
||||
return responseJson.gitVersion;
|
||||
}
|
||||
|
||||
protected isGKE() {
|
||||
@ -158,7 +158,7 @@ export class DistributionDetector extends BaseClusterDetector {
|
||||
protected isK0s() {
|
||||
return this.version.includes("-k0s");
|
||||
}
|
||||
|
||||
|
||||
protected isAlibaba() {
|
||||
return this.version.includes("-aliyun");
|
||||
}
|
||||
@ -169,9 +169,9 @@ export class DistributionDetector extends BaseClusterDetector {
|
||||
|
||||
protected async isOpenshift() {
|
||||
try {
|
||||
const response = await this.k8sRequest("");
|
||||
const [, responseJson] = await this.k8sRequest<any>("");
|
||||
|
||||
return response.paths?.includes("/apis/project.openshift.io");
|
||||
return responseJson.paths?.includes("/apis/project.openshift.io");
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ export class LastSeenDetector extends BaseClusterDetector {
|
||||
public async detect() {
|
||||
if (!this.cluster.accessible) return null;
|
||||
|
||||
await this.k8sRequest("/version");
|
||||
await this.k8sRequest<any>("/version");
|
||||
|
||||
return { value: new Date().toJSON(), accuracy: 100 };
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ export class NodesCountDetector extends BaseClusterDetector {
|
||||
}
|
||||
|
||||
protected async getNodeCount(): Promise<number> {
|
||||
const response = await this.k8sRequest("/api/v1/nodes");
|
||||
const [, responseJson] = await this.k8sRequest<any>("/api/v1/nodes");
|
||||
|
||||
return response.items.length;
|
||||
return responseJson.items.length;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,8 @@ export class VersionDetector extends BaseClusterDetector {
|
||||
}
|
||||
|
||||
public async getKubernetesVersion() {
|
||||
const response = await this.k8sRequest("/version");
|
||||
const [, responseJson] = await this.k8sRequest<any>("/version", { retry: 0 });
|
||||
|
||||
return response.gitVersion;
|
||||
return responseJson.gitVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ import logger from "./logger";
|
||||
import { VersionDetector } from "./cluster-detectors/version-detector";
|
||||
import { detectorRegistry } from "./cluster-detectors/detector-registry";
|
||||
import plimit from "p-limit";
|
||||
import got, { OptionsOfJSONResponseBody } from "got";
|
||||
import got, { OptionsOfJSONResponseBody, Response } from "got";
|
||||
import { URL } from "url";
|
||||
|
||||
export enum ClusterStatus {
|
||||
@ -51,6 +51,24 @@ export interface ClusterState {
|
||||
isGlobalWatchEnabled: boolean;
|
||||
}
|
||||
|
||||
export async function k8sRequest<T = any>(url: string | URL, options: OptionsOfJSONResponseBody = {}): Promise<[Response<T>, T]> {
|
||||
options.timeout ??= 5000;
|
||||
options.headers ??= {};
|
||||
options.headers["content-type"] ??= "application/json";
|
||||
options.throwHttpErrors ??= true;
|
||||
|
||||
try {
|
||||
const resp = got<T>(url, options);
|
||||
const jsonResp = resp.json<T>();
|
||||
|
||||
return await Promise.all([resp, jsonResp]);
|
||||
} catch(error) {
|
||||
logger.error(`[REQUEST]: failed to get ${url}`, { error });
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cluster
|
||||
*
|
||||
@ -495,7 +513,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
return this.kubeconfigManager.getPath();
|
||||
}
|
||||
|
||||
private getUrlTo(path: string): URL {
|
||||
public getUrlTo(path: string): URL {
|
||||
const url = new URL(this.kubeProxyUrl.toString());
|
||||
|
||||
url.pathname += path;
|
||||
@ -538,34 +556,36 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
const versionData = await versionDetector.detect();
|
||||
|
||||
this.metadata.version = versionData.value;
|
||||
|
||||
this.failureReason = null;
|
||||
|
||||
return ClusterStatus.AccessGranted;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to connect cluster "${this.contextName}": ${error}`);
|
||||
logger.error(`Failed to connect cluster "${this.contextName}"`, { error });
|
||||
|
||||
if (error instanceof got.TimeoutError) {
|
||||
this.failureReason = "Connection timed out";
|
||||
|
||||
return ClusterStatus.Offline;
|
||||
}
|
||||
|
||||
if (error.statusCode) {
|
||||
if (error.statusCode >= 400 && error.statusCode < 500) {
|
||||
this.failureReason = "Invalid credentials";
|
||||
|
||||
return ClusterStatus.AccessDenied;
|
||||
} else {
|
||||
this.failureReason = error.error || error.message;
|
||||
|
||||
return ClusterStatus.Offline;
|
||||
}
|
||||
} else if (error.failed === true) {
|
||||
if (error.timedOut === true) {
|
||||
this.failureReason = "Connection timed out";
|
||||
|
||||
return ClusterStatus.Offline;
|
||||
} else {
|
||||
this.failureReason = "Failed to fetch credentials";
|
||||
this.failureReason = error.error || error.message;
|
||||
|
||||
return ClusterStatus.AccessDenied;
|
||||
}
|
||||
return ClusterStatus.Offline;
|
||||
}
|
||||
|
||||
if (error.failed === true) {
|
||||
this.failureReason = "Failed to fetch credentials";
|
||||
|
||||
return ClusterStatus.AccessDenied;
|
||||
}
|
||||
|
||||
this.failureReason = error.message;
|
||||
|
||||
return ClusterStatus.Offline;
|
||||
|
||||
@ -12,15 +12,17 @@ export interface MetricsQuery {
|
||||
// prometheus metrics loader
|
||||
async function loadMetrics(promQueries: string[], cluster: Cluster, prometheusPath: string, queryParams: Record<string, string>): Promise<any[]> {
|
||||
const queries = promQueries.map(p => p.trim());
|
||||
const loaders = new Map<string, Promise<any>>();
|
||||
const loaders = new Map<string, ReturnType<(typeof cluster)["getMetrics"]>>();
|
||||
|
||||
async function loadMetric(query: string): Promise<any> {
|
||||
async function loadMetric(query: string) {
|
||||
const searchParams = { query, ...queryParams };
|
||||
|
||||
return loaders.get(query) ?? loaders.set(query, cluster.getMetrics(prometheusPath, { searchParams, retry: 5 })).get(query);
|
||||
}
|
||||
|
||||
return Promise.all(queries.map(loadMetric));
|
||||
const responses = await Promise.all(queries.map(loadMetric));
|
||||
|
||||
return responses.map(([, respJson]) => respJson);
|
||||
}
|
||||
|
||||
export interface MetricsResult {
|
||||
@ -69,7 +71,7 @@ class MetricsRoute extends LensApi {
|
||||
}
|
||||
prometheusMetadata.success = true;
|
||||
} catch (error) {
|
||||
logger.error("[METRICS]: failed to load metrics", { error });
|
||||
logger.error(`[METRICS]: failed to load metrics: ${error}`, { error });
|
||||
|
||||
prometheusMetadata.success = false;
|
||||
this.respondJson(response, {});
|
||||
|
||||
@ -170,8 +170,7 @@ export class Extensions extends React.Component {
|
||||
// install via url
|
||||
// fixme: improve error messages for non-tar-file URLs
|
||||
if (InputValidators.isUrl.validate(installPath)) {
|
||||
const { promise: filePromise } = downloadFile({ url: installPath, timeout: 60000 /*1m*/ });
|
||||
const data = await filePromise;
|
||||
const data = await downloadFile({ url: installPath, timeout: 60000 /*1m*/ });
|
||||
|
||||
await this.requestInstall({ fileName, data });
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
click: actions.showSettings
|
||||
}));
|
||||
|
||||
if (cluster.online) {
|
||||
if (cluster.online || cluster.failureReason) {
|
||||
menu.append(new MenuItem({
|
||||
label: `Disconnect`,
|
||||
click: actions.disconnect
|
||||
|
||||
@ -1682,14 +1682,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.28.tgz#6bda7db8653fa62643f5ee69e9f69c11a392e3a6"
|
||||
integrity sha1-a9p9uGU/piZD9e5p6facEaOS46Y=
|
||||
|
||||
"@types/request-promise-native@^1.0.17":
|
||||
version "1.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/request-promise-native/-/request-promise-native-1.0.17.tgz#74a2d7269aebf18b9bdf35f01459cf0a7bfc7fab"
|
||||
integrity sha512-05/d0WbmuwjtGMYEdHIBZ0tqMJJQ2AD9LG2F6rKNBGX1SSFR27XveajH//2N/XYtual8T9Axwl+4v7oBtPUZqg==
|
||||
dependencies:
|
||||
"@types/request" "*"
|
||||
|
||||
"@types/request@*", "@types/request@^2.47.1", "@types/request@^2.48.5":
|
||||
"@types/request@^2.47.1":
|
||||
version "2.48.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0"
|
||||
integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==
|
||||
|
||||
Loading…
Reference in New Issue
Block a user