1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Adding kubectl binaries section in Preferences

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2020-09-03 14:39:43 +03:00
parent 43f3044273
commit 75825d0628
5 changed files with 99 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import type { ThemeId } from "../renderer/theme.store"; import type { ThemeId } from "../renderer/theme.store";
import { app, remote } from 'electron';
import semver from "semver" import semver from "semver"
import { readFile } from "fs-extra" import { readFile } from "fs-extra"
import { action, observable, reaction, toJS } from "mobx"; import { action, observable, reaction, toJS } from "mobx";
@ -8,6 +9,7 @@ import { getAppVersion } from "./utils/app-version";
import { kubeConfigDefaultPath, loadConfig } from "./kube-helpers"; import { kubeConfigDefaultPath, loadConfig } from "./kube-helpers";
import { tracker } from "./tracker"; import { tracker } from "./tracker";
import logger from "../main/logger"; import logger from "../main/logger";
import path from 'path';
export interface UserStoreModel { export interface UserStoreModel {
kubeConfigPath: string; kubeConfigPath: string;
@ -22,6 +24,9 @@ export interface UserPreferences {
allowUntrustedCAs?: boolean; allowUntrustedCAs?: boolean;
allowTelemetry?: boolean; allowTelemetry?: boolean;
downloadMirror?: string | "default"; downloadMirror?: string | "default";
downloadKubectlBinaries?: boolean;
downloadBinariesPath?: string;
kubectlBinariesPath?: string;
} }
export class UserStore extends BaseStore<UserStoreModel> { export class UserStore extends BaseStore<UserStoreModel> {
@ -53,6 +58,9 @@ export class UserStore extends BaseStore<UserStoreModel> {
allowUntrustedCAs: false, allowUntrustedCAs: false,
colorTheme: UserStore.defaultTheme, colorTheme: UserStore.defaultTheme,
downloadMirror: "default", downloadMirror: "default",
downloadKubectlBinaries: true, // Download kubectl binaries matching cluster version
downloadBinariesPath: "",
kubectlBinariesPath: "$PATH/kubectl"
}; };
get isNewVersion() { get isNewVersion() {
@ -98,6 +106,14 @@ export class UserStore extends BaseStore<UserStoreModel> {
this.newContexts.clear(); this.newContexts.clear();
} }
/**
* Getting default directory to download kubectl binaries
* @returns string
*/
getDefaultKubectlPath(): string {
return path.join((app || remote.app).getPath("userData"), "binaries")
}
@action @action
protected async fromStore(data: Partial<UserStoreModel> = {}) { protected async fromStore(data: Partial<UserStoreModel> = {}) {
const { lastSeenAppVersion, seenContexts = [], preferences, kubeConfigPath } = data const { lastSeenAppVersion, seenContexts = [], preferences, kubeConfigPath } = data

View File

@ -0,0 +1,68 @@
import React, { useState } from 'react';
import { Trans } from '@lingui/macro';
import { isPath } from '../input/input.validators';
import { Checkbox } from '../checkbox';
import { Input } from '../input';
import { SubTitle } from '../layout/sub-title';
import { UserPreferences, userStore } from '../../../common/user-store';
import { observer } from 'mobx-react';
export const KubectlBinaries = observer(({ preferences }: { preferences: UserPreferences }) => {
const [downloadPath, setDownloadPath] = useState(preferences.downloadBinariesPath || "");
const [binariesPath, setBinariesPath] = useState(preferences.kubectlBinariesPath || "");
const save = () => {
preferences.downloadBinariesPath = downloadPath;
preferences.kubectlBinariesPath = binariesPath;
}
const renderPath = () => {
if (preferences.downloadKubectlBinaries) {
return null;
}
return (
<>
<SubTitle title="Path to Kubectl binary"/>
<Input
theme="round-black"
value={binariesPath}
validators={isPath}
onChange={setBinariesPath}
onBlur={save}
/>
<small className="hint">
<Trans>Default: $PATH/kubectl</Trans>
</small>
</>
);
}
return (
<>
<h2><Trans>Kubectl Binary</Trans></h2>
<small className="hint">
<Trans>Download kubectl binaries matching to Kubernetes cluster verison.</Trans>
</small>
<Checkbox
label={<Trans>Download kubectl binaries</Trans>}
value={preferences.downloadKubectlBinaries}
onChange={() =>
preferences.downloadKubectlBinaries = !preferences.downloadKubectlBinaries
}
/>
<Input
theme="round-black"
value={downloadPath}
placeholder={`Directory to download binaries into`}
validators={isPath}
onChange={setDownloadPath}
onBlur={save}
disabled={!preferences.downloadKubectlBinaries}
/>
<small>
Default: {userStore.getDefaultKubectlPath()}
</small>
{renderPath()}
</>
);
});

View File

@ -19,6 +19,11 @@
} }
} }
.SubTitle {
text-transform: none;
margin: 0!important;
}
.repos { .repos {
position: relative; position: relative;

View File

@ -16,6 +16,7 @@ import { Badge } from "../badge";
import { themeStore } from "../../theme.store"; import { themeStore } from "../../theme.store";
import { history } from "../../navigation"; import { history } from "../../navigation";
import { Tooltip } from "../tooltip"; import { Tooltip } from "../tooltip";
import { KubectlBinaries } from "./kubectl-binaries";
@observer @observer
export class Preferences extends React.Component { export class Preferences extends React.Component {
@ -169,6 +170,8 @@ export class Preferences extends React.Component {
<Trans>Proxy is used only for non-cluster communication.</Trans> <Trans>Proxy is used only for non-cluster communication.</Trans>
</small> </small>
<KubectlBinaries preferences={preferences} />
<h2><Trans>Certificate Trust</Trans></h2> <h2><Trans>Certificate Trust</Trans></h2>
<Checkbox <Checkbox
label={<Trans>Allow untrusted Certificate Authorities</Trans>} label={<Trans>Allow untrusted Certificate Authorities</Trans>}

View File

@ -2,6 +2,7 @@ import type { InputProps } from "./input";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { _i18n } from '../../i18n'; import { _i18n } from '../../i18n';
import fse from "fs-extra";
export interface Validator { export interface Validator {
debounce?: number; // debounce for async validators in ms debounce?: number; // debounce for async validators in ms
@ -41,6 +42,12 @@ export const isUrl: Validator = {
validate: value => !!value.match(/^http(s)?:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]*)*$/), validate: value => !!value.match(/^http(s)?:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]*)*$/),
}; };
export const isPath: Validator = {
condition: ({ type }) => type === "text",
message: () => _i18n._(t`This field must be a path to an existing file`),
validate: value => fse.pathExistsSync(value),
}
export const minLength: Validator = { export const minLength: Validator = {
condition: ({ minLength }) => !!minLength, condition: ({ minLength }) => !!minLength,
message: (value, { minLength }) => _i18n._(t`Minimum length is ${minLength}`), message: (value, { minLength }) => _i18n._(t`Minimum length is ${minLength}`),