mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix check for user exec command (#3664)
This commit is contained in:
parent
068c78d48d
commit
056b818ceb
@ -185,6 +185,7 @@
|
|||||||
"@kubernetes/client-node": "^0.15.1",
|
"@kubernetes/client-node": "^0.15.1",
|
||||||
"@sentry/electron": "^2.5.0",
|
"@sentry/electron": "^2.5.0",
|
||||||
"@sentry/integrations": "^6.10.0",
|
"@sentry/integrations": "^6.10.0",
|
||||||
|
"@types/which": "^2.0.1",
|
||||||
"abort-controller": "^3.0.0",
|
"abort-controller": "^3.0.0",
|
||||||
"array-move": "^3.0.1",
|
"array-move": "^3.0.1",
|
||||||
"auto-bind": "^4.0.0",
|
"auto-bind": "^4.0.0",
|
||||||
@ -193,7 +194,6 @@
|
|||||||
"byline": "^5.0.0",
|
"byline": "^5.0.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"chokidar": "^3.4.3",
|
"chokidar": "^3.4.3",
|
||||||
"command-exists": "1.2.9",
|
|
||||||
"conf": "^7.0.1",
|
"conf": "^7.0.1",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"electron-devtools-installer": "^3.2.0",
|
"electron-devtools-installer": "^3.2.0",
|
||||||
@ -246,6 +246,7 @@
|
|||||||
"tempy": "^0.5.0",
|
"tempy": "^0.5.0",
|
||||||
"url-parse": "^1.5.1",
|
"url-parse": "^1.5.1",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
"which": "^2.0.2",
|
||||||
"win-ca": "^3.2.0",
|
"win-ca": "^3.2.0",
|
||||||
"winston": "^3.3.3",
|
"winston": "^3.3.3",
|
||||||
"winston-console-format": "^1.0.8",
|
"winston-console-format": "^1.0.8",
|
||||||
|
|||||||
@ -19,15 +19,18 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
export class ExecValidationNotFoundError extends Error {
|
export class ExecValidationNotFoundError extends Error {
|
||||||
constructor(execPath: string, isAbsolute: boolean) {
|
constructor(execPath: string) {
|
||||||
super(`User Exec command "${execPath}" not found on host.`);
|
|
||||||
let message = `User Exec command "${execPath}" not found on host.`;
|
let message = `User Exec command "${execPath}" not found on host.`;
|
||||||
|
|
||||||
if (!isAbsolute) {
|
if (!path.isAbsolute(execPath)) {
|
||||||
message += ` Please ensure binary is found in PATH or use absolute path to binary in Kubeconfig`;
|
message += ` Please ensure binary is found in PATH or use absolute path to binary in Kubeconfig`;
|
||||||
}
|
}
|
||||||
this.message = message;
|
|
||||||
|
super(message);
|
||||||
|
|
||||||
this.name = this.constructor.name;
|
this.name = this.constructor.name;
|
||||||
Error.captureStackTrace(this, this.constructor);
|
Error.captureStackTrace(this, this.constructor);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,11 +25,11 @@ import path from "path";
|
|||||||
import os from "os";
|
import os from "os";
|
||||||
import yaml from "js-yaml";
|
import yaml from "js-yaml";
|
||||||
import logger from "../main/logger";
|
import logger from "../main/logger";
|
||||||
import commandExists from "command-exists";
|
|
||||||
import { ExecValidationNotFoundError } from "./custom-errors";
|
import { ExecValidationNotFoundError } from "./custom-errors";
|
||||||
import { Cluster, Context, newClusters, newContexts, newUsers, User } from "@kubernetes/client-node/dist/config_types";
|
import { Cluster, Context, newClusters, newContexts, newUsers, User } from "@kubernetes/client-node/dist/config_types";
|
||||||
import { resolvePath } from "./utils";
|
import { resolvePath } from "./utils";
|
||||||
import Joi from "joi";
|
import Joi from "joi";
|
||||||
|
import which from "which";
|
||||||
|
|
||||||
export type KubeConfigValidationOpts = {
|
export type KubeConfigValidationOpts = {
|
||||||
validateCluster?: boolean;
|
validateCluster?: boolean;
|
||||||
@ -295,13 +295,17 @@ export function validateKubeConfig(config: KubeConfig, contextName: string, vali
|
|||||||
|
|
||||||
// Validate exec command if present
|
// Validate exec command if present
|
||||||
if (validateExec && user?.exec) {
|
if (validateExec && user?.exec) {
|
||||||
const execCommand = user.exec["command"];
|
try {
|
||||||
// check if the command is absolute or not
|
which.sync(user.exec.command);
|
||||||
const isAbsolute = path.isAbsolute(execCommand);
|
|
||||||
|
|
||||||
// validate the exec struct in the user object, start with the command field
|
// If this doesn't throw an error it also means that it has found the executable.
|
||||||
if (!commandExists.sync(execCommand)) {
|
} catch (error) {
|
||||||
return new ExecValidationNotFoundError(execCommand, isAbsolute);
|
switch (error?.code) {
|
||||||
|
case "ENOENT":
|
||||||
|
return new ExecValidationNotFoundError(user.exec.command);
|
||||||
|
default:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,4 +50,11 @@
|
|||||||
display: block;
|
display: block;
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actions-panel {
|
||||||
|
.Spinner {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: $spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import "./add-cluster.scss";
|
|||||||
import type { KubeConfig } from "@kubernetes/client-node";
|
import type { KubeConfig } from "@kubernetes/client-node";
|
||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
import { debounce } from "lodash";
|
import { debounce } from "lodash";
|
||||||
import { action, computed, observable, makeObservable } from "mobx";
|
import { action, computed, observable, makeObservable, runInAction } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
@ -41,6 +41,7 @@ import { SettingLayout } from "../layout/setting-layout";
|
|||||||
import MonacoEditor from "react-monaco-editor";
|
import MonacoEditor from "react-monaco-editor";
|
||||||
import { ThemeStore } from "../../theme.store";
|
import { ThemeStore } from "../../theme.store";
|
||||||
import { UserStore } from "../../../common/user-store";
|
import { UserStore } from "../../../common/user-store";
|
||||||
|
import { Spinner } from "../spinner";
|
||||||
|
|
||||||
interface Option {
|
interface Option {
|
||||||
config: KubeConfig;
|
config: KubeConfig;
|
||||||
@ -62,6 +63,7 @@ export class AddCluster extends React.Component {
|
|||||||
@observable kubeContexts = observable.map<string, Option>();
|
@observable kubeContexts = observable.map<string, Option>();
|
||||||
@observable customConfig = "";
|
@observable customConfig = "";
|
||||||
@observable isWaiting = false;
|
@observable isWaiting = false;
|
||||||
|
@observable isCheckingInput = false;
|
||||||
@observable errorText: string;
|
@observable errorText: string;
|
||||||
|
|
||||||
constructor(props: {}) {
|
constructor(props: {}) {
|
||||||
@ -80,14 +82,35 @@ export class AddCluster extends React.Component {
|
|||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
_refreshContexts = debounce(() => {
|
||||||
refreshContexts = debounce(() => {
|
runInAction(() => {
|
||||||
const { config, error } = loadConfigFromString(this.customConfig.trim() || "{}");
|
try {
|
||||||
|
const text = this.customConfig.trim();
|
||||||
|
|
||||||
this.kubeContexts.replace(getContexts(config));
|
if (!text) {
|
||||||
this.errorText = error?.toString();
|
return this.kubeContexts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const { config, error } = loadConfigFromString(text);
|
||||||
|
|
||||||
|
this.kubeContexts.replace(getContexts(config));
|
||||||
|
this.errorText = error?.toString();
|
||||||
|
} catch (error) {
|
||||||
|
this.kubeContexts.clear();
|
||||||
|
this.errorText = error?.toString() || "An error occured";
|
||||||
|
} finally {
|
||||||
|
this.isCheckingInput = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
refreshContexts = () => {
|
||||||
|
// Clear the kubeContexts immediately
|
||||||
|
this.isCheckingInput = true;
|
||||||
|
this.kubeContexts.clear();
|
||||||
|
this._refreshContexts();
|
||||||
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
addClusters = async () => {
|
addClusters = async () => {
|
||||||
this.isWaiting = true;
|
this.isWaiting = true;
|
||||||
@ -145,6 +168,7 @@ export class AddCluster extends React.Component {
|
|||||||
tooltip={this.kubeContexts.size === 0 || "Paste in at least one cluster to add."}
|
tooltip={this.kubeContexts.size === 0 || "Paste in at least one cluster to add."}
|
||||||
tooltipOverrideDisabled
|
tooltipOverrideDisabled
|
||||||
/>
|
/>
|
||||||
|
{this.isCheckingInput && <Spinner />}
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</SettingLayout>
|
||||||
);
|
);
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@ -2184,6 +2184,11 @@
|
|||||||
anymatch "^3.0.0"
|
anymatch "^3.0.0"
|
||||||
source-map "^0.6.0"
|
source-map "^0.6.0"
|
||||||
|
|
||||||
|
"@types/which@^2.0.1":
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/which/-/which-2.0.1.tgz#27ecd67f915b7c3d6ba552135bb1eecd66e63501"
|
||||||
|
integrity sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==
|
||||||
|
|
||||||
"@types/ws@^6.0.1":
|
"@types/ws@^6.0.1":
|
||||||
version "6.0.4"
|
version "6.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1"
|
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1"
|
||||||
@ -4110,11 +4115,6 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
command-exists@1.2.9:
|
|
||||||
version "1.2.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69"
|
|
||||||
integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==
|
|
||||||
|
|
||||||
commander@2.9.0:
|
commander@2.9.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user