mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge remote-tracking branch 'origin/master' into pages-url-params
# Conflicts: # src/renderer/components/+namespaces/namespace.store.ts
This commit is contained in:
commit
77d218486b
@ -39,7 +39,7 @@ spec:
|
||||
serviceAccountName: kube-state-metrics
|
||||
containers:
|
||||
- name: kube-state-metrics
|
||||
image: quay.io/coreos/kube-state-metrics:v1.9.5
|
||||
image: quay.io/coreos/kube-state-metrics:v1.9.7
|
||||
ports:
|
||||
- name: metrics
|
||||
containerPort: 8080
|
||||
|
||||
@ -26,7 +26,7 @@ export interface MetricsConfiguration {
|
||||
|
||||
export class MetricsFeature extends ClusterFeature.Feature {
|
||||
name = "metrics";
|
||||
latestVersion = "v2.17.2-lens1";
|
||||
latestVersion = "v2.17.2-lens2";
|
||||
|
||||
templateContext: MetricsConfiguration = {
|
||||
persistence: {
|
||||
|
||||
@ -120,6 +120,14 @@ export class LensProxy {
|
||||
protected createProxy(): httpProxy {
|
||||
const proxy = httpProxy.createProxyServer();
|
||||
|
||||
proxy.on("proxyRes", (proxyRes, req) => {
|
||||
const retryCounterId = this.getRequestId(req);
|
||||
|
||||
if (this.retryCounters.has(retryCounterId)) {
|
||||
this.retryCounters.delete(retryCounterId);
|
||||
}
|
||||
});
|
||||
|
||||
proxy.on("error", (error, req, res, target) => {
|
||||
if (this.closed) {
|
||||
return;
|
||||
|
||||
@ -13,6 +13,7 @@ import { crdStore } from "./crd.store";
|
||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||
import { Input } from "../input";
|
||||
import { AdditionalPrinterColumnsV1, CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
||||
import { parseJsonPath } from "../../utils/jsonPath";
|
||||
|
||||
interface Props extends KubeObjectDetailsProps<CustomResourceDefinition> {
|
||||
}
|
||||
@ -46,7 +47,7 @@ export class CrdResourceDetails extends React.Component<Props> {
|
||||
renderAdditionalColumns(crd: CustomResourceDefinition, columns: AdditionalPrinterColumnsV1[]) {
|
||||
return columns.map(({ name, jsonPath: jp }) => (
|
||||
<DrawerItem key={name} name={name} renderBoolean>
|
||||
{convertSpecValue(jsonPath.value(crd, jp.slice(1)))}
|
||||
{convertSpecValue(jsonPath.value(crd, parseJsonPath(jp.slice(1))))}
|
||||
</DrawerItem>
|
||||
));
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import { autorun, computed } from "mobx";
|
||||
import { crdStore } from "./crd.store";
|
||||
import { TableSortCallback } from "../table";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { parseJsonPath } from "../../utils/jsonPath";
|
||||
|
||||
interface Props extends RouteComponentProps<ICRDRouteParams> {
|
||||
}
|
||||
@ -61,7 +62,7 @@ export class CrdResources extends React.Component<Props> {
|
||||
};
|
||||
|
||||
extraColumns.forEach(column => {
|
||||
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.value(item, column.jsonPath.slice(1));
|
||||
sortingCallbacks[column.name] = (item: KubeObject) => jsonPath.value(item, parseJsonPath(column.jsonPath.slice(1)));
|
||||
});
|
||||
|
||||
return (
|
||||
@ -91,10 +92,18 @@ export class CrdResources extends React.Component<Props> {
|
||||
renderTableContents={(crdInstance: KubeObject) => [
|
||||
crdInstance.getName(),
|
||||
isNamespaced && crdInstance.getNs(),
|
||||
...extraColumns.map(column => ({
|
||||
renderBoolean: true,
|
||||
children: JSON.stringify(jsonPath.value(crdInstance, column.jsonPath.slice(1))),
|
||||
})),
|
||||
...extraColumns.map((column) => {
|
||||
let value = jsonPath.value(crdInstance, parseJsonPath(column.jsonPath.slice(1)));
|
||||
|
||||
if (Array.isArray(value) || typeof value === "object") {
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
|
||||
return {
|
||||
renderBoolean: true,
|
||||
children: value,
|
||||
};
|
||||
}),
|
||||
crdInstance.getAge(),
|
||||
]}
|
||||
/>
|
||||
|
||||
@ -51,10 +51,10 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
|
||||
subscribe(apis = [this.api]) {
|
||||
const { allowedNamespaces } = getHostedCluster();
|
||||
const { accessibleNamespaces } = getHostedCluster();
|
||||
|
||||
// if user has given static list of namespaces let's not start watches because watch adds stuff that's not wanted
|
||||
if (allowedNamespaces.length > 0) {
|
||||
if (accessibleNamespaces.length > 0) {
|
||||
return Function; // no-op
|
||||
}
|
||||
|
||||
|
||||
@ -134,7 +134,7 @@ export class Nodes extends React.Component<Props> {
|
||||
<KubeObjectListLayout
|
||||
className="Nodes"
|
||||
store={nodesStore} isClusterScoped
|
||||
isReady={nodesStore.isLoaded && nodesStore.metricsLoaded}
|
||||
isReady={nodesStore.isLoaded}
|
||||
dependentStores={[podsStore]}
|
||||
isSelectable={false}
|
||||
sortingCallbacks={{
|
||||
|
||||
41
src/renderer/utils/__tests__/jsonPath.test.tsx
Normal file
41
src/renderer/utils/__tests__/jsonPath.test.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { parseJsonPath } from "../jsonPath";
|
||||
|
||||
describe("parseJsonPath", () => {
|
||||
test("should convert \\. to use indexed notation", () => {
|
||||
const res = parseJsonPath(".metadata.labels.kubesphere\\.io/alias-name");
|
||||
|
||||
expect(res).toBe(".metadata.labels['kubesphere.io/alias-name']");
|
||||
});
|
||||
|
||||
test("should convert keys with escpaped charatecrs to use indexed notation", () => {
|
||||
const res = parseJsonPath(".metadata.labels.kubesphere\\\"io/alias-name");
|
||||
|
||||
expect(res).toBe(".metadata.labels['kubesphere\"io/alias-name']");
|
||||
});
|
||||
|
||||
test("should convert '-' to use indexed notation", () => {
|
||||
const res = parseJsonPath(".metadata.labels.alias-name");
|
||||
|
||||
expect(res).toBe(".metadata.labels['alias-name']");
|
||||
});
|
||||
|
||||
test("should handle scenario when both \\. and indexed notation are present", () => {
|
||||
const rest = parseJsonPath(".metadata.labels\\.serving['some.other.item']");
|
||||
|
||||
expect(rest).toBe(".metadata['labels.serving']['some.other.item']");
|
||||
});
|
||||
|
||||
|
||||
test("should not touch given jsonPath if no invalid characters present", () => {
|
||||
const res = parseJsonPath(".status.conditions[?(@.type=='Ready')].status");
|
||||
|
||||
expect(res).toBe(".status.conditions[?(@.type=='Ready')].status");
|
||||
});
|
||||
|
||||
test("strips '\\' away from the result", () => {
|
||||
const res = parseJsonPath(".metadata.labels['serving\\.knative\\.dev/configuration']");
|
||||
|
||||
expect(res).toBe(".metadata.labels['serving.knative.dev/configuration']");
|
||||
});
|
||||
|
||||
});
|
||||
35
src/renderer/utils/jsonPath.ts
Normal file
35
src/renderer/utils/jsonPath.ts
Normal file
@ -0,0 +1,35 @@
|
||||
// Helper to convert strings used for jsonPath where \. or - is present to use indexed notation,
|
||||
// for example: .metadata.labels.kubesphere\.io/alias-name -> .metadata.labels['kubesphere\.io/alias-name']
|
||||
|
||||
export function parseJsonPath(jsonPath: string) {
|
||||
let pathExpression = jsonPath;
|
||||
|
||||
if (jsonPath.match(/[\\-]/g)) { // search for '\' and '-'
|
||||
const [first, ...rest] = jsonPath.split(/(?<=\w)\./); // split jsonPath by '.' (\. cases are ignored)
|
||||
|
||||
pathExpression = `${convertToIndexNotation(first, true)}${rest.map(value => convertToIndexNotation(value)).join("")}`;
|
||||
}
|
||||
|
||||
// strip '\' characters from the result
|
||||
return pathExpression.replace(/\\/g, "");
|
||||
}
|
||||
|
||||
function convertToIndexNotation(key: string, firstItem = false) {
|
||||
if (key.match(/[\\-]/g)) { // check if found '\' and '-' in key
|
||||
if (key.includes("[")) { // handle cases where key contains [...]
|
||||
const keyToConvert = key.match(/^.*(?=\[)/g); // get the text from the key before '['
|
||||
|
||||
if (keyToConvert && keyToConvert[0].match(/[\\-]/g)) { // check if that part contains illegal characters
|
||||
return key.replace(keyToConvert[0], `['${keyToConvert[0]}']`); // surround key with '[' and ']'
|
||||
} else {
|
||||
return `.${key}`; // otherwise return as is with leading '.'
|
||||
}
|
||||
}
|
||||
|
||||
return `['${key}']`;
|
||||
} else { // no illegal chracters found, do not touch
|
||||
const prefix = firstItem ? "" : ".";
|
||||
|
||||
return `${prefix}${key}`;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user