diff --git a/src/common/kube-helpers.ts b/src/common/kube-helpers.ts index bb0e6b86d2..eb0cd4ec8a 100644 --- a/src/common/kube-helpers.ts +++ b/src/common/kube-helpers.ts @@ -151,18 +151,42 @@ export function getNodeWarningConditions(node: V1Node) { } /** - * Validates kubeconfig supplied in the add clusters screen. At present this will just validate - * the User struct, specifically the command passed to the exec substructure. - */ -export function validateKubeConfig (config: KubeConfig) { + * Validates kubeconfig supplied in the add clusters screen. Additionally this will just validate + * the User struct, specifically the command passed to the exec substructure. + */ +export function validateKubeConfig (config: KubeConfig, contextName: string, validationOpts?: { validateCluster?: boolean, validateUser?: boolean, validateExec?: boolean}) { // we only receive a single context, cluster & user object here so lets validate them as this // will be called when we add a new cluster to Lens logger.debug(`validateKubeConfig: validating kubeconfig - ${JSON.stringify(config)}`); + const defaultOpts = { + validateContext: true, + validateUser: true, + validateCluster: true, + validateExec: true + }; + const opts = {...defaultOpts, ...validationOpts }; + + const contextObject = config.getContextObject(contextName); + + // Validate the Context Object + if (!contextObject) { + throw new Error(`No valid context object provided in kubeconfig for context '${contextName}'`); + } + + // Validate the Cluster Object + if (opts.validateCluster && !config.getCluster(contextObject.cluster)) { + throw new Error(`No valid cluster object provided in kubeconfig for context '${contextName}'`); + } + + const user = config.getUser(contextObject.user); // Validate the User Object - const user = config.getCurrentUser(); - - if (user.exec) { + if (opts.validateUser && !user) { + throw new Error(`No valid user object provided in kubeconfig for context '${contextName}'`); + } + + // Validate exec command if present + if (opts.validateExec && user.exec) { const execCommand = user.exec["command"]; // check if the command is absolute or not const isAbsolute = path.isAbsolute(execCommand); @@ -171,7 +195,7 @@ export function validateKubeConfig (config: KubeConfig) { logger.debug(`validateKubeConfig: validating user exec command - ${JSON.stringify(execCommand)}`); if (!commandExists.sync(execCommand)) { - logger.debug(`validateKubeConfig: exec command ${String(execCommand)} in kubeconfig ${config.currentContext} not found`); + logger.debug(`validateKubeConfig: exec command ${String(execCommand)} in kubeconfig ${contextName} not found`); throw new ExecValidationNotFoundError(execCommand, isAbsolute); } } diff --git a/src/main/cluster.ts b/src/main/cluster.ts index b4037151fa..125d2ce959 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -9,7 +9,7 @@ import { ContextHandler } from "./context-handler"; import { AuthorizationV1Api, CoreV1Api, KubeConfig, V1ResourceAttributes } from "@kubernetes/client-node"; import { Kubectl } from "./kubectl"; import { KubeconfigManager } from "./kubeconfig-manager"; -import { loadConfig } from "../common/kube-helpers"; +import { loadConfig, validateKubeConfig } from "../common/kube-helpers"; import request, { RequestPromiseOptions } from "request-promise-native"; import { apiResources, KubeApiResource } from "../common/rbac"; import logger from "./logger"; @@ -252,10 +252,11 @@ export class Cluster implements ClusterModel, ClusterState { try { const kubeconfig = this.getKubeconfig(); + validateKubeConfig(kubeconfig, this.contextName, { validateCluster: true, validateUser: false, validateExec: false}); this.apiUrl = kubeconfig.getCluster(kubeconfig.getContextObject(this.contextName).cluster).server; } catch(err) { logger.error(err); - logger.error(`[CLUSTER] Failed to load kubeconfig for the cluster (context: ${this.contextName}, kubeconfig: ${this.kubeConfigPath}).`); + logger.error(`[CLUSTER] Failed to load kubeconfig for the cluster '${this.name || this.contextName}' (context: ${this.contextName}, kubeconfig: ${this.kubeConfigPath}).`); this.isDead = true; } } diff --git a/src/renderer/components/+add-cluster/add-cluster.tsx b/src/renderer/components/+add-cluster/add-cluster.tsx index ae4a3e6ace..38d03482e8 100644 --- a/src/renderer/components/+add-cluster/add-cluster.tsx +++ b/src/renderer/components/+add-cluster/add-cluster.tsx @@ -147,7 +147,7 @@ export class AddCluster extends React.Component { try { const kubeConfig = this.kubeContexts.get(context); - validateKubeConfig(kubeConfig); + validateKubeConfig(kubeConfig, context); return true; } catch (err) {