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

Upgrade js-yaml to 4.X (#3623)

This commit is contained in:
Sebastian Malton 2021-10-18 10:03:10 -04:00 committed by GitHub
parent fcb3010033
commit 5998b4ca84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 90 additions and 57 deletions

View File

@ -207,7 +207,7 @@
"http-proxy": "^1.18.1", "http-proxy": "^1.18.1",
"immer": "^9.0.6", "immer": "^9.0.6",
"joi": "^17.4.2", "joi": "^17.4.2",
"js-yaml": "^3.14.0", "js-yaml": "^4.1.0",
"jsdom": "^16.7.0", "jsdom": "^16.7.0",
"jsonpath": "^1.1.1", "jsonpath": "^1.1.1",
"lodash": "^4.17.15", "lodash": "^4.17.15",
@ -277,7 +277,7 @@
"@types/html-webpack-plugin": "^3.2.6", "@types/html-webpack-plugin": "^3.2.6",
"@types/http-proxy": "^1.17.7", "@types/http-proxy": "^1.17.7",
"@types/jest": "^26.0.24", "@types/jest": "^26.0.24",
"@types/js-yaml": "^3.12.4", "@types/js-yaml": "^4.0.2",
"@types/jsdom": "^16.2.13", "@types/jsdom": "^16.2.13",
"@types/jsonpath": "^0.2.0", "@types/jsonpath": "^0.2.0",
"@types/lodash": "^4.14.155", "@types/lodash": "^4.14.155",

View File

@ -426,7 +426,7 @@ describe("pre 2.6.0 config with a cluster that has arrays in auth config", () =>
it("replaces array format access token and expiry into string", async () => { it("replaces array format access token and expiry into string", async () => {
const file = ClusterStore.getInstance().clustersList[0].kubeConfigPath; const file = ClusterStore.getInstance().clustersList[0].kubeConfigPath;
const config = fs.readFileSync(file, "utf8"); const config = fs.readFileSync(file, "utf8");
const kc = yaml.safeLoad(config); const kc = yaml.load(config) as Record<string, any>;
expect(kc.users[0].user["auth-provider"].config["access-token"]).toBe("should be string"); expect(kc.users[0].user["auth-provider"].config["access-token"]).toBe("should be string");
expect(kc.users[0].user["auth-provider"].config["expiry"]).toBe("should be string"); expect(kc.users[0].user["auth-provider"].config["expiry"]).toBe("should be string");

View File

@ -19,7 +19,7 @@
* 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 jsYaml from "js-yaml"; import yaml from "js-yaml";
import { autoBind, formatDuration } from "../../utils"; import { autoBind, formatDuration } from "../../utils";
import capitalize from "lodash/capitalize"; import capitalize from "lodash/capitalize";
import { apiBase } from "../index"; import { apiBase } from "../index";
@ -113,21 +113,31 @@ export async function getRelease(name: string, namespace: string): Promise<IRele
} }
export async function createRelease(payload: IReleaseCreatePayload): Promise<IReleaseUpdateDetails> { export async function createRelease(payload: IReleaseCreatePayload): Promise<IReleaseUpdateDetails> {
const { repo, ...data } = payload; const { repo, chart: rawChart, values: rawValues, ...data } = payload;
const chart = `${repo}/${rawChart}`;
const values = yaml.load(rawValues);
data.chart = `${repo}/${data.chart}`; return apiBase.post(endpoint(), {
data.values = jsYaml.safeLoad(data.values); data: {
chart,
return apiBase.post(endpoint(), { data }); values,
...data,
}
});
} }
export async function updateRelease(name: string, namespace: string, payload: IReleaseUpdatePayload): Promise<IReleaseUpdateDetails> { export async function updateRelease(name: string, namespace: string, payload: IReleaseUpdatePayload): Promise<IReleaseUpdateDetails> {
const { repo, ...data } = payload; const { repo, chart: rawChart, values: rawValues, ...data } = payload;
const chart = `${repo}/${rawChart}`;
const values = yaml.load(rawValues);
data.chart = `${repo}/${data.chart}`; return apiBase.put(endpoint({ name, namespace }), {
data.values = jsYaml.safeLoad(data.values); data: {
chart,
return apiBase.put(endpoint({ name, namespace }), { data }); values,
...data,
}
});
} }
export async function deleteRelease(name: string, namespace: string): Promise<JsonApiData> { export async function deleteRelease(name: string, namespace: string): Promise<JsonApiData> {

View File

@ -19,7 +19,7 @@
* 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 jsYaml from "js-yaml"; import yaml from "js-yaml";
import type { KubeJsonApiData } from "../kube-json-api"; import type { KubeJsonApiData } from "../kube-json-api";
import { apiBase } from "../index"; import { apiBase } from "../index";
import type { Patch } from "rfc6902"; import type { Patch } from "rfc6902";
@ -30,7 +30,13 @@ export const annotations = [
export async function update(resource: object | string): Promise<KubeJsonApiData> { export async function update(resource: object | string): Promise<KubeJsonApiData> {
if (typeof resource === "string") { if (typeof resource === "string") {
resource = jsYaml.safeLoad(resource); const parsed = yaml.load(resource);
if (typeof parsed !== "object") {
throw new Error("Cannot update resource to string or number");
}
resource = parsed;
} }
return apiBase.post<KubeJsonApiData>("/stack", { data: resource }); return apiBase.post<KubeJsonApiData>("/stack", { data: resource });

View File

@ -133,7 +133,7 @@ export class ResourceStack {
if (!resourceData.trim()) continue; if (!resourceData.trim()) continue;
const resourceArray = yaml.safeLoadAll(resourceData.toString()); const resourceArray = yaml.loadAll(resourceData.toString());
resourceArray.forEach((resource) => { resourceArray.forEach((resource) => {
if (resource?.metadata) { if (resource?.metadata) {
@ -143,7 +143,7 @@ export class ResourceStack {
resource.metadata.labels["app.kubernetes.io/created-by"] = "resource-stack"; resource.metadata.labels["app.kubernetes.io/created-by"] = "resource-stack";
} }
resources.push(yaml.safeDump(resource)); resources.push(yaml.dump(resource));
}); });
} }

View File

@ -111,7 +111,7 @@ interface OptionsResult {
} }
function loadToOptions(rawYaml: string): OptionsResult { function loadToOptions(rawYaml: string): OptionsResult {
const parsed = yaml.safeLoad(rawYaml); const parsed = yaml.load(rawYaml);
const { error } = kubeConfigSchema.validate(parsed, { const { error } = kubeConfigSchema.validate(parsed, {
abortEarly: false, abortEarly: false,
allowUnknown: true, allowUnknown: true,
@ -248,7 +248,7 @@ export function dumpConfigYaml(kubeConfig: Partial<KubeConfig>): string {
logger.debug("Dumping KubeConfig:", config); logger.debug("Dumping KubeConfig:", config);
// skipInvalid: true makes dump ignore undefined values // skipInvalid: true makes dump ignore undefined values
return yaml.safeDump(config, { skipInvalid: true }); return yaml.dump(config, { skipInvalid: true });
} }
/** /**

View File

@ -29,6 +29,11 @@ import { helmCli } from "./helm-cli";
import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api"; import type { RepoHelmChartList } from "../../common/k8s-api/endpoints/helm-charts.api";
import { sortCharts } from "../../common/utils"; import { sortCharts } from "../../common/utils";
export interface HelmCacheFile {
apiVersion: string;
entries: RepoHelmChartList;
}
export class HelmChartManager { export class HelmChartManager {
static #cache = new Map<string, Buffer>(); static #cache = new Map<string, Buffer>();
@ -82,7 +87,11 @@ export class HelmChartManager {
protected async cachedYaml(): Promise<RepoHelmChartList> { protected async cachedYaml(): Promise<RepoHelmChartList> {
if (!HelmChartManager.#cache.has(this.repo.name)) { if (!HelmChartManager.#cache.has(this.repo.name)) {
const cacheFile = await fs.promises.readFile(this.repo.cacheFilePath, "utf-8"); const cacheFile = await fs.promises.readFile(this.repo.cacheFilePath, "utf-8");
const { entries } = yaml.safeLoad(cacheFile) as { entries: RepoHelmChartList }; const data = yaml.load(cacheFile) as string | number | HelmCacheFile;
if (typeof data !== "object" || !data) {
return {};
}
/** /**
* Do some initial preprocessing on the data, so as to avoid needing to do it later * Do some initial preprocessing on the data, so as to avoid needing to do it later
@ -92,7 +101,7 @@ export class HelmChartManager {
*/ */
const normalized = Object.fromEntries( const normalized = Object.fromEntries(
Object.entries(entries) Object.entries(data.entries)
.map(([name, charts]) => [ .map(([name, charts]) => [
name, name,
sortCharts( sortCharts(

View File

@ -53,7 +53,7 @@ export async function installChart(chart: string, values: any, name: string | un
const helm = await helmCli.binaryPath(); const helm = await helmCli.binaryPath();
const fileName = tempy.file({ name: "values.yaml" }); const fileName = tempy.file({ name: "values.yaml" });
await fse.writeFile(fileName, yaml.safeDump(values)); await fse.writeFile(fileName, yaml.dump(values));
try { try {
let generateName = ""; let generateName = "";
@ -83,7 +83,7 @@ export async function upgradeRelease(name: string, chart: string, values: any, n
const helm = await helmCli.binaryPath(); const helm = await helmCli.binaryPath();
const fileName = tempy.file({ name: "values.yaml" }); const fileName = tempy.file({ name: "values.yaml" });
await fse.writeFile(fileName, yaml.safeDump(values)); await fse.writeFile(fileName, yaml.dump(values));
try { try {
const proxyKubeconfig = await cluster.getProxyKubeconfigPath(); const proxyKubeconfig = await cluster.getProxyKubeconfigPath();

View File

@ -101,18 +101,28 @@ export class HelmRepoManager extends Singleton {
return repos.find(repo => repo.name === name); return repos.find(repo => repo.name === name);
} }
private async readConfig(): Promise<HelmRepoConfig> {
try {
const rawConfig = await readFile(this.helmEnv.HELM_REPOSITORY_CONFIG, "utf8");
const parsedConfig = yaml.load(rawConfig);
if (typeof parsedConfig === "object" && parsedConfig) {
return parsedConfig as HelmRepoConfig;
}
} catch { }
return {
repositories: []
};
}
public async repositories(): Promise<HelmRepo[]> { public async repositories(): Promise<HelmRepo[]> {
try { try {
if (!this.initialized) { if (!this.initialized) {
await this.init(); await this.init();
} }
const repoConfigFile = this.helmEnv.HELM_REPOSITORY_CONFIG; const { repositories } = await this.readConfig();
const { repositories }: HelmRepoConfig = await readFile(repoConfigFile, "utf8")
.then((yamlContent: string) => yaml.safeLoad(yamlContent))
.catch(() => ({
repositories: []
}));
if (!repositories.length) { if (!repositories.length) {
await HelmRepoManager.addRepo({ name: "bitnami", url: "https://charts.bitnami.com/bitnami" }); await HelmRepoManager.addRepo({ name: "bitnami", url: "https://charts.bitnami.com/bitnami" });

View File

@ -78,7 +78,7 @@ export class ResourceApplier {
resource = this.sanitizeObject(resource); resource = this.sanitizeObject(resource);
appEventBus.emit({ name: "resource", action: "apply" }); appEventBus.emit({ name: "resource", action: "apply" });
return this.kubectlApply(yaml.safeDump(resource)); return this.kubectlApply(yaml.dump(resource));
} }
protected async kubectlApply(content: string): Promise<string> { protected async kubectlApply(content: string): Promise<string> {

View File

@ -32,9 +32,13 @@ export default {
const cluster = value[1]; const cluster = value[1];
if (!cluster.kubeConfig) continue; if (!cluster.kubeConfig) continue;
const kubeConfig = yaml.safeLoad(cluster.kubeConfig); const config = yaml.load(cluster.kubeConfig);
if (!kubeConfig.hasOwnProperty("users")) continue; if (!config || typeof config !== "object" || !config.hasOwnProperty("users")) {
continue;
}
const kubeConfig = config as Record<string, any>;
const userObj = kubeConfig.users[0]; const userObj = kubeConfig.users[0];
if (userObj) { if (userObj) {
@ -56,7 +60,7 @@ export default {
name: userObj.name, name: userObj.name,
user user
}]; }];
cluster.kubeConfig = yaml.safeDump(kubeConfig); cluster.kubeConfig = yaml.dump(kubeConfig);
store.set(clusterKey, cluster); store.set(clusterKey, cluster);
} }
} }

View File

@ -21,7 +21,7 @@
import "./pod-details-affinities.scss"; import "./pod-details-affinities.scss";
import React from "react"; import React from "react";
import jsYaml from "js-yaml"; import yaml from "js-yaml";
import { DrawerParamToggler, DrawerItem } from "../drawer"; import { DrawerParamToggler, DrawerItem } from "../drawer";
import type { Pod, Deployment, DaemonSet, StatefulSet, ReplicaSet, Job } from "../../../common/k8s-api/endpoints"; import type { Pod, Deployment, DaemonSet, StatefulSet, ReplicaSet, Job } from "../../../common/k8s-api/endpoints";
import MonacoEditor from "react-monaco-editor"; import MonacoEditor from "react-monaco-editor";
@ -50,7 +50,7 @@ export class PodDetailsAffinities extends React.Component<Props> {
className={cssNames("MonacoEditor")} className={cssNames("MonacoEditor")}
theme={ThemeStore.getInstance().activeTheme.monacoTheme} theme={ThemeStore.getInstance().activeTheme.monacoTheme}
language="yaml" language="yaml"
value={jsYaml.dump(affinities)} value={yaml.dump(affinities)}
/> />
</div> </div>
</DrawerParamToggler> </DrawerParamToggler>

View File

@ -25,7 +25,7 @@ import React from "react";
import path from "path"; import path from "path";
import fs from "fs-extra"; import fs from "fs-extra";
import {Select, GroupSelectOption, SelectOption} from "../select"; import {Select, GroupSelectOption, SelectOption} from "../select";
import jsYaml from "js-yaml"; import yaml from "js-yaml";
import { observable, makeObservable } from "mobx"; import { observable, makeObservable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { cssNames } from "../../utils"; import { cssNames } from "../../utils";
@ -101,15 +101,14 @@ export class CreateResource extends React.Component<Props> {
return null; return null;
} }
// skip empty documents if "---" pasted at the beginning or end // skip empty documents
const resources = jsYaml.safeLoadAll(this.data).filter(Boolean); const resources = yaml.loadAll(this.data).filter(Boolean);
const createdResources: string[] = [];
if (resources.length === 0) { if (resources.length === 0) {
return void logger.info("Nothing to create"); return void logger.info("Nothing to create");
} }
const createdResources: string[] = [];
for (const result of await Promise.allSettled(resources.map(resourceApplierApi.update))) { for (const result of await Promise.allSettled(resources.map(resourceApplierApi.update))) {
if (result.status === "fulfilled") { if (result.status === "fulfilled") {
createdResources.push(result.value.metadata.name); createdResources.push(result.value.metadata.name);

View File

@ -72,13 +72,13 @@ export class EditResource extends React.Component<Props> {
return draft; return draft;
} }
return yaml.safeDump(this.resource.toPlainObject()); // dump resource first time return yaml.dump(this.resource.toPlainObject()); // dump resource first time
} }
@action @action
saveDraft(draft: string | object) { saveDraft(draft: string | object) {
if (typeof draft === "object") { if (typeof draft === "object") {
draft = draft ? yaml.safeDump(draft) : undefined; draft = draft ? yaml.dump(draft) : undefined;
} }
editResourceStore.setData(this.tabId, { editResourceStore.setData(this.tabId, {
@ -99,8 +99,8 @@ export class EditResource extends React.Component<Props> {
} }
const store = editResourceStore.getStore(this.tabId); const store = editResourceStore.getStore(this.tabId);
const currentVersion = yaml.safeLoad(this.draft); const currentVersion = yaml.load(this.draft);
const firstVersion = yaml.safeLoad(editResourceStore.getData(this.tabId).firstDraft ?? this.draft); const firstVersion = yaml.load(editResourceStore.getData(this.tabId).firstDraft ?? this.draft);
const patches = createPatch(firstVersion, currentVersion); const patches = createPatch(firstVersion, currentVersion);
const updatedResource = await store.patch(this.resource, patches); const updatedResource = await store.patch(this.resource, patches);

View File

@ -21,7 +21,7 @@
import MonacoEditor, {monaco} from "react-monaco-editor"; import MonacoEditor, {monaco} from "react-monaco-editor";
import React from "react"; import React from "react";
import jsYaml from "js-yaml"; import yaml from "js-yaml";
import { observable, makeObservable } from "mobx"; import { observable, makeObservable } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { dockStore, TabId } from "./dock.store"; import { dockStore, TabId } from "./dock.store";
@ -70,7 +70,7 @@ export class EditorPanel extends React.Component<Props> {
validate(value: string) { validate(value: string) {
try { try {
jsYaml.safeLoadAll(value); yaml.loadAll(value);
this.yamlError = ""; this.yamlError = "";
} catch (err) { } catch (err) {
this.yamlError = err.toString(); this.yamlError = err.toString();

View File

@ -24,7 +24,7 @@ import "./kubeconfig-dialog.scss";
import React from "react"; import React from "react";
import { observable, makeObservable } from "mobx"; import { observable, makeObservable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import jsYaml from "js-yaml"; import yaml from "js-yaml";
import type { ServiceAccount } from "../../../common/k8s-api/endpoints"; import type { ServiceAccount } from "../../../common/k8s-api/endpoints";
import { copyToClipboard, cssNames, saveFileDialog } from "../../utils"; import { copyToClipboard, cssNames, saveFileDialog } from "../../utils";
import { Button } from "../button"; import { Button } from "../button";
@ -88,7 +88,7 @@ export class KubeConfigDialog extends React.Component<Props> {
this.close(); this.close();
}); });
this.config = config ? jsYaml.dump(config) : ""; this.config = config ? yaml.dump(config) : "";
} }
copyToClipboard = () => { copyToClipboard = () => {

View File

@ -1611,12 +1611,7 @@
jest-diff "^26.0.0" jest-diff "^26.0.0"
pretty-format "^26.0.0" pretty-format "^26.0.0"
"@types/js-yaml@^3.12.4": "@types/js-yaml@^4.0.1", "@types/js-yaml@^4.0.2":
version "3.12.4"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.4.tgz#7d3b534ec35a0585128e2d332db1403ebe057e25"
integrity sha512-fYMgzN+9e28R81weVN49inn/u798ruU91En1ZnGvSZzCRc5jXx9B2EDhlRaWmcO1RIxFHL8AajRXzxDuJu93+A==
"@types/js-yaml@^4.0.1":
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.2.tgz#4117a7a378593a218e9d6f0ef44ce6d5d9edf7fa" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.2.tgz#4117a7a378593a218e9d6f0ef44ce6d5d9edf7fa"
integrity sha512-KbeHS/Y4R+k+5sWXEYzAZKuB1yQlZtEghuhRxrVRLaqhtoG5+26JwQsa4HyS3AWX8v1Uwukma5HheduUDskasA== integrity sha512-KbeHS/Y4R+k+5sWXEYzAZKuB1yQlZtEghuhRxrVRLaqhtoG5+26JwQsa4HyS3AWX8v1Uwukma5HheduUDskasA==
@ -8468,7 +8463,7 @@ js-sha3@^0.8.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^3.13.1, js-yaml@^3.14.0: js-yaml@^3.13.1:
version "3.14.1" version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==