mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
release v5.5.2 (#5504)
Co-authored-by: Lauri Nevala <lauri.nevala@gmail.com> Co-authored-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
07e9456874
commit
e3cb23e111
@ -24,11 +24,6 @@ spec:
|
|||||||
operator: In
|
operator: In
|
||||||
values:
|
values:
|
||||||
- linux
|
- linux
|
||||||
- matchExpressions:
|
|
||||||
- key: beta.kubernetes.io/os
|
|
||||||
operator: In
|
|
||||||
values:
|
|
||||||
- linux
|
|
||||||
# <%- if config.node_selector -%>
|
# <%- if config.node_selector -%>
|
||||||
# nodeSelector:
|
# nodeSelector:
|
||||||
# <%- node_selector.to_h.each do |key, value| -%>
|
# <%- node_selector.to_h.each do |key, value| -%>
|
||||||
|
|||||||
@ -30,11 +30,6 @@ spec:
|
|||||||
operator: In
|
operator: In
|
||||||
values:
|
values:
|
||||||
- linux
|
- linux
|
||||||
- matchExpressions:
|
|
||||||
- key: beta.kubernetes.io/os
|
|
||||||
operator: In
|
|
||||||
values:
|
|
||||||
- linux
|
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
runAsUser: 65534
|
runAsUser: 65534
|
||||||
|
|||||||
@ -23,11 +23,6 @@ spec:
|
|||||||
operator: In
|
operator: In
|
||||||
values:
|
values:
|
||||||
- linux
|
- linux
|
||||||
- matchExpressions:
|
|
||||||
- key: beta.kubernetes.io/os
|
|
||||||
operator: In
|
|
||||||
values:
|
|
||||||
- linux
|
|
||||||
serviceAccountName: kube-state-metrics
|
serviceAccountName: kube-state-metrics
|
||||||
containers:
|
containers:
|
||||||
- name: kube-state-metrics
|
- name: kube-state-metrics
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
"productName": "OpenLens",
|
"productName": "OpenLens",
|
||||||
"description": "OpenLens - Open Source IDE for Kubernetes",
|
"description": "OpenLens - Open Source IDE for Kubernetes",
|
||||||
"homepage": "https://github.com/lensapp/lens",
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
"version": "5.5.1",
|
"version": "5.5.2",
|
||||||
"main": "static/build/main.js",
|
"main": "static/build/main.js",
|
||||||
"copyright": "© 2021 OpenLens Authors",
|
"copyright": "© 2021 OpenLens Authors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -72,6 +72,9 @@
|
|||||||
"<rootDir>/src/jest.setup.ts",
|
"<rootDir>/src/jest.setup.ts",
|
||||||
"jest-canvas-mock"
|
"jest-canvas-mock"
|
||||||
],
|
],
|
||||||
|
"setupFilesAfterEnv": [
|
||||||
|
"<rootDir>/src/jest-after-env.setup.ts"
|
||||||
|
],
|
||||||
"globals": {
|
"globals": {
|
||||||
"ts-jest": {
|
"ts-jest": {
|
||||||
"isolatedModules": true
|
"isolatedModules": true
|
||||||
|
|||||||
@ -279,8 +279,10 @@ export interface CephfsSource {
|
|||||||
secretRef?: SecretReference;
|
secretRef?: SecretReference;
|
||||||
/**
|
/**
|
||||||
* Whether the filesystem is used as readOnly.
|
* Whether the filesystem is used as readOnly.
|
||||||
|
*
|
||||||
|
* @default false
|
||||||
*/
|
*/
|
||||||
readOnly: boolean;
|
readOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CinderSource {
|
export interface CinderSource {
|
||||||
@ -430,46 +432,62 @@ export interface PortworxVolumeSource {
|
|||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProjectedSource {
|
export interface KeyToPath {
|
||||||
sources: {
|
|
||||||
secret?: {
|
|
||||||
name: string;
|
|
||||||
items?: {
|
|
||||||
key: string;
|
key: string;
|
||||||
path: string;
|
path: string;
|
||||||
mode?: number;
|
mode?: number;
|
||||||
}[];
|
}
|
||||||
};
|
|
||||||
downwardAPI?: {
|
export interface ConfigMapProjection {
|
||||||
items?: {
|
name: string;
|
||||||
path: string;
|
items?: KeyToPath[];
|
||||||
fieldRef?: {
|
optional?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ObjectFieldSelector {
|
||||||
fieldPath: string;
|
fieldPath: string;
|
||||||
apiVersion?: string;
|
apiVersion?: string;
|
||||||
};
|
}
|
||||||
resourceFieldRef?: {
|
|
||||||
|
export interface ResourceFieldSelector {
|
||||||
resource: string;
|
resource: string;
|
||||||
containerName?: string;
|
containerName?: string;
|
||||||
};
|
divisor?: string;
|
||||||
mode?: number;
|
}
|
||||||
}[];
|
|
||||||
};
|
export interface DownwardAPIVolumeFile {
|
||||||
configMap?: {
|
|
||||||
name: string;
|
|
||||||
items?: {
|
|
||||||
key: string;
|
|
||||||
path: string;
|
path: string;
|
||||||
|
fieldRef?: ObjectFieldSelector;
|
||||||
|
resourceFieldRef?: ResourceFieldSelector;
|
||||||
mode?: number;
|
mode?: number;
|
||||||
}[];
|
}
|
||||||
|
|
||||||
|
export interface DownwardAPIProjection {
|
||||||
|
items?: DownwardAPIVolumeFile[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecretProjection {
|
||||||
|
name: string;
|
||||||
|
items?: KeyToPath[];
|
||||||
optional?: boolean;
|
optional?: boolean;
|
||||||
};
|
}
|
||||||
serviceAccountToken?: {
|
|
||||||
|
export interface ServiceAccountTokenProjection {
|
||||||
audience?: string;
|
audience?: string;
|
||||||
expirationSeconds?: number;
|
expirationSeconds?: number;
|
||||||
path: string;
|
path: string;
|
||||||
};
|
}
|
||||||
}[];
|
|
||||||
defaultMode: number;
|
export interface VolumeProjection {
|
||||||
|
secret?: SecretProjection;
|
||||||
|
downwardAPI?: DownwardAPIProjection;
|
||||||
|
configMap?: ConfigMapProjection;
|
||||||
|
serviceAccountToken?: ServiceAccountTokenProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProjectedSource {
|
||||||
|
sources?: VolumeProjection[];
|
||||||
|
defaultMode?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuobyteSource {
|
export interface QuobyteSource {
|
||||||
|
|||||||
@ -43,6 +43,7 @@ export interface KubeJsonApiData extends JsonApiData {
|
|||||||
kind: string;
|
kind: string;
|
||||||
apiVersion: string;
|
apiVersion: string;
|
||||||
metadata: KubeJsonApiMetadata;
|
metadata: KubeJsonApiMetadata;
|
||||||
|
spec?: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface KubeJsonApiError extends JsonApiError {
|
export interface KubeJsonApiError extends JsonApiError {
|
||||||
|
|||||||
5
src/jest-after-env.setup.ts
Normal file
5
src/jest-after-env.setup.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import "@testing-library/jest-dom/extend-expect";
|
||||||
@ -0,0 +1,229 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<Projected /> renders 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Sources
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Projected /> renders a secret source including overriding mode 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Default Mount Mode
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
0o777
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Sources
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="DrawerTitle sub-title"
|
||||||
|
>
|
||||||
|
Secret
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
my-projected-secret
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Items
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
foo⇢/bar
|
||||||
|
(0o666)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Projected /> renders a secret source, when provided 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Default Mount Mode
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
0o777
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Sources
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="DrawerTitle sub-title"
|
||||||
|
>
|
||||||
|
Secret
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
my-projected-secret
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Items
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
foo⇢/bar
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Projected /> renders default mount mode in octal when provided 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Default Mount Mode
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
0o777
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Sources
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<Projected /> renders when no sources array provided 1`] = `
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Default Mount Mode
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
0o777
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Sources
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
`;
|
||||||
@ -0,0 +1,229 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`<CephFs /> should render 'false' for Readonly when false is provided 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Monitors
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<ul />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Mount Path
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Username
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
admin
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Secret Filepath
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/etc/ceph/user.secret
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
data-testid="cephfs-readonly"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Readonly
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
false
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<CephFs /> should render 'false' for Readonly when not provided 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Monitors
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<ul />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Mount Path
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Username
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
admin
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Secret Filepath
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/etc/ceph/user.secret
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
data-testid="cephfs-readonly"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Readonly
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
false
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`<CephFs /> should render 'true' for Readonly when true is provided 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Monitors
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
<ul />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Mount Path
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Username
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
admin
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Secret Filepath
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
/etc/ceph/user.secret
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="DrawerItem"
|
||||||
|
data-testid="cephfs-readonly"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="name"
|
||||||
|
>
|
||||||
|
Readonly
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="value"
|
||||||
|
>
|
||||||
|
true
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { render } from "@testing-library/react";
|
||||||
|
import React from "react";
|
||||||
|
import type { CephfsSource } from "../../../../../../../common/k8s-api/endpoints";
|
||||||
|
import { Pod } from "../../../../../../../common/k8s-api/endpoints";
|
||||||
|
import { CephFs } from "../ceph-fs";
|
||||||
|
|
||||||
|
describe("<CephFs />", () => {
|
||||||
|
it("should render 'false' for Readonly when not provided", () => {
|
||||||
|
const cephfsName = "my-ceph";
|
||||||
|
const cephfsVolume: CephfsSource = {
|
||||||
|
monitors: [],
|
||||||
|
};
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: cephfsName,
|
||||||
|
cephfs: cephfsVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<CephFs
|
||||||
|
pod={pod}
|
||||||
|
variant={cephfsVolume}
|
||||||
|
volumeName={cephfsName}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.container).toMatchSnapshot();
|
||||||
|
expect(result.getByTestId("cephfs-readonly")).toHaveTextContent("false");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render 'false' for Readonly when false is provided", () => {
|
||||||
|
const cephfsName = "my-ceph";
|
||||||
|
const cephfsVolume: CephfsSource = {
|
||||||
|
monitors: [],
|
||||||
|
readOnly: false,
|
||||||
|
};
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: cephfsName,
|
||||||
|
cephfs: cephfsVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<CephFs
|
||||||
|
pod={pod}
|
||||||
|
variant={cephfsVolume}
|
||||||
|
volumeName={cephfsName}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.container).toMatchSnapshot();
|
||||||
|
expect(result.getByTestId("cephfs-readonly")).toHaveTextContent("false");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render 'true' for Readonly when true is provided", () => {
|
||||||
|
const cephfsName = "my-ceph";
|
||||||
|
const cephfsVolume: CephfsSource = {
|
||||||
|
monitors: [],
|
||||||
|
readOnly: true,
|
||||||
|
};
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: cephfsName,
|
||||||
|
cephfs: cephfsVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<CephFs
|
||||||
|
pod={pod}
|
||||||
|
variant={cephfsVolume}
|
||||||
|
volumeName={cephfsName}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.container).toMatchSnapshot();
|
||||||
|
expect(result.getByTestId("cephfs-readonly")).toHaveTextContent("true");
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -10,7 +10,7 @@ import type { VolumeVariantComponent } from "../variant-helpers";
|
|||||||
import { LocalRef } from "../variant-helpers";
|
import { LocalRef } from "../variant-helpers";
|
||||||
|
|
||||||
export const CephFs: VolumeVariantComponent<"cephfs"> = (
|
export const CephFs: VolumeVariantComponent<"cephfs"> = (
|
||||||
({ pod, variant: { monitors, path = "/", user = "admin", secretFile = "/etc/ceph/user.secret", secretRef, readOnly }}) => (
|
({ pod, variant: { monitors, path = "/", user = "admin", secretFile = "/etc/ceph/user.secret", secretRef, readOnly = false }}) => (
|
||||||
<>
|
<>
|
||||||
<DrawerItem name="Monitors">
|
<DrawerItem name="Monitors">
|
||||||
<ul>
|
<ul>
|
||||||
@ -39,7 +39,7 @@ export const CephFs: VolumeVariantComponent<"cephfs"> = (
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<DrawerItem name="Readonly">
|
<DrawerItem name="Readonly" data-testid="cephfs-readonly">
|
||||||
{readOnly.toString()}
|
{readOnly.toString()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { render } from "@testing-library/react";
|
||||||
|
import React from "react";
|
||||||
|
import type { ProjectedSource } from "../../../../../../common/k8s-api/endpoints";
|
||||||
|
import { Pod } from "../../../../../../common/k8s-api/endpoints";
|
||||||
|
import { Projected } from "./projected";
|
||||||
|
|
||||||
|
describe("<Projected />", () => {
|
||||||
|
it("renders", () => {
|
||||||
|
const projectedVolume: ProjectedSource = { };
|
||||||
|
const projectedVolumeName = "my-projected";
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: projectedVolumeName,
|
||||||
|
projected: projectedVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<Projected
|
||||||
|
pod={pod}
|
||||||
|
volumeName={projectedVolumeName}
|
||||||
|
variant={projectedVolume}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders default mount mode in octal when provided", () => {
|
||||||
|
const projectedVolume: ProjectedSource = {
|
||||||
|
defaultMode: 0o777,
|
||||||
|
sources: [],
|
||||||
|
};
|
||||||
|
const projectedVolumeName = "my-projected";
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: projectedVolumeName,
|
||||||
|
projected: projectedVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<Projected
|
||||||
|
pod={pod}
|
||||||
|
volumeName={projectedVolumeName}
|
||||||
|
variant={projectedVolume}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders when no sources array provided", () => {
|
||||||
|
const projectedVolume: ProjectedSource = {
|
||||||
|
defaultMode: 0o777,
|
||||||
|
};
|
||||||
|
const projectedVolumeName = "my-projected";
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: projectedVolumeName,
|
||||||
|
projected: projectedVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<Projected
|
||||||
|
pod={pod}
|
||||||
|
volumeName={projectedVolumeName}
|
||||||
|
variant={projectedVolume}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.baseElement).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders a secret source, when provided", () => {
|
||||||
|
const projectedVolume: ProjectedSource = {
|
||||||
|
defaultMode: 0o777,
|
||||||
|
sources: [{
|
||||||
|
secret: {
|
||||||
|
name: "my-projected-secret",
|
||||||
|
items: [{
|
||||||
|
key: "foo",
|
||||||
|
path: "/bar",
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
const projectedVolumeName = "my-projected";
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: projectedVolumeName,
|
||||||
|
projected: projectedVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<Projected
|
||||||
|
pod={pod}
|
||||||
|
volumeName={projectedVolumeName}
|
||||||
|
variant={projectedVolume}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.baseElement).toMatchSnapshot();
|
||||||
|
expect(result.getByText("foo⇢/bar", { exact: false })).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders a secret source including overriding mode", () => {
|
||||||
|
const projectedVolume: ProjectedSource = {
|
||||||
|
defaultMode: 0o777,
|
||||||
|
sources: [{
|
||||||
|
secret: {
|
||||||
|
name: "my-projected-secret",
|
||||||
|
items: [{
|
||||||
|
key: "foo",
|
||||||
|
path: "/bar",
|
||||||
|
mode: 0o666,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
const projectedVolumeName = "my-projected";
|
||||||
|
const pod = new Pod({
|
||||||
|
apiVersion: "v1",
|
||||||
|
kind: "Pod",
|
||||||
|
metadata: {
|
||||||
|
name: "my-pod",
|
||||||
|
namespace: "default",
|
||||||
|
resourceVersion: "1",
|
||||||
|
uid: "123",
|
||||||
|
selfLink: "/api/v1/pod/default/my-pod",
|
||||||
|
},
|
||||||
|
spec: {
|
||||||
|
volumes: [{
|
||||||
|
name: projectedVolumeName,
|
||||||
|
projected: projectedVolume,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const result = render((
|
||||||
|
<Projected
|
||||||
|
pod={pod}
|
||||||
|
volumeName={projectedVolumeName}
|
||||||
|
variant={projectedVolume}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
expect(result.baseElement).toMatchSnapshot();
|
||||||
|
expect(result.getByText("(0o666)", { exact: false })).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -4,18 +4,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { displayMode } from "../../../../../utils";
|
||||||
import { DrawerItem, DrawerTitle } from "../../../../drawer";
|
import { DrawerItem, DrawerTitle } from "../../../../drawer";
|
||||||
import type { VolumeVariantComponent } from "../variant-helpers";
|
import type { VolumeVariantComponent } from "../variant-helpers";
|
||||||
|
|
||||||
export const Projected: VolumeVariantComponent<"projected"> = (
|
export const Projected: VolumeVariantComponent<"projected"> = (
|
||||||
({ variant: { sources, defaultMode }}) => (
|
({ variant: { sources, defaultMode }}) => (
|
||||||
<>
|
<>
|
||||||
|
{typeof defaultMode === "number" && (
|
||||||
<DrawerItem name="Default Mount Mode">
|
<DrawerItem name="Default Mount Mode">
|
||||||
0o{defaultMode.toString(8)}
|
{displayMode(defaultMode)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
)}
|
||||||
<DrawerItem name="Sources">
|
<DrawerItem name="Sources">
|
||||||
{
|
{
|
||||||
sources.map(({ secret, downwardAPI, configMap, serviceAccountToken }, index) => (
|
sources?.map(({ secret, downwardAPI, configMap, serviceAccountToken }, index) => (
|
||||||
<React.Fragment key={index}>
|
<React.Fragment key={index}>
|
||||||
{secret && (
|
{secret && (
|
||||||
<>
|
<>
|
||||||
@ -25,9 +28,12 @@ export const Projected: VolumeVariantComponent<"projected"> = (
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name="Items">
|
<DrawerItem name="Items">
|
||||||
<ul>
|
<ul>
|
||||||
{secret.items?.map(({ key, path }) => (
|
{secret.items?.map(({ key, path, mode }) => (
|
||||||
<li key={key}>
|
<li key={key}>
|
||||||
{key} ⇢ {path}
|
{`${key}⇢${path}`}
|
||||||
|
{typeof mode === "number" && (
|
||||||
|
` (${displayMode(mode)})`
|
||||||
|
)}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { debounce, merge } from "lodash";
|
|||||||
import { autoBind, cssNames, disposer } from "../../utils";
|
import { autoBind, cssNames, disposer } from "../../utils";
|
||||||
import { UserStore } from "../../../common/user-store";
|
import { UserStore } from "../../../common/user-store";
|
||||||
import { ThemeStore } from "../../theme.store";
|
import { ThemeStore } from "../../theme.store";
|
||||||
import logger from "../../../main/logger";
|
|
||||||
|
|
||||||
export type MonacoEditorId = string;
|
export type MonacoEditorId = string;
|
||||||
|
|
||||||
@ -60,6 +59,12 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
|
|||||||
@observable readonly dimensions: { width?: number; height?: number } = {};
|
@observable readonly dimensions: { width?: number; height?: number } = {};
|
||||||
@observable private unmounting = false;
|
@observable private unmounting = false;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: investigate how to replace with "common/logger"
|
||||||
|
// currently leads for stucking UI forever & infinite loop.
|
||||||
|
// e.g. happens on tab change/create, maybe some other cases too.
|
||||||
|
private logger = console;
|
||||||
|
|
||||||
constructor(props: MonacoEditorProps) {
|
constructor(props: MonacoEditorProps) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
@ -119,7 +124,7 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected onModelChange(model: editor.ITextModel, oldModel?: editor.ITextModel) {
|
protected onModelChange(model: editor.ITextModel, oldModel?: editor.ITextModel) {
|
||||||
logger.info("[MONACO]: model change", { model, oldModel }, this.logMetadata);
|
this.logger.info("[MONACO]: model change", { model, oldModel }, this.logMetadata);
|
||||||
|
|
||||||
if (oldModel) {
|
if (oldModel) {
|
||||||
this.saveViewState(oldModel);
|
this.saveViewState(oldModel);
|
||||||
@ -152,9 +157,9 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
try {
|
try {
|
||||||
this.createEditor();
|
this.createEditor();
|
||||||
logger.info(`[MONACO]: editor did mount`, this.logMetadata);
|
this.logger.info(`[MONACO]: editor did mount`, this.logMetadata);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`[MONACO]: mounting failed: ${error}`, this.logMetadata);
|
this.logger.error(`[MONACO]: mounting failed: ${error}`, this.logMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +185,7 @@ export class MonacoEditor extends React.Component<MonacoEditorProps> {
|
|||||||
...this.options,
|
...this.options,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info(`[MONACO]: editor created for language=${language}, theme=${theme}`, this.logMetadata);
|
this.logger.info(`[MONACO]: editor created for language=${language}, theme=${theme}`, this.logMetadata);
|
||||||
this.validateLazy(); // validate initial value
|
this.validateLazy(); // validate initial value
|
||||||
this.restoreViewState(this.model); // restore previous state if any
|
this.restoreViewState(this.model); // restore previous state if any
|
||||||
|
|
||||||
|
|||||||
11
src/renderer/utils/display-mode.ts
Normal file
11
src/renderer/utils/display-mode.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format `mode` in octal notation
|
||||||
|
*/
|
||||||
|
export function displayMode(mode: number): string {
|
||||||
|
return `0o${mode.toString(8)}`;
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ export * from "../../common/event-emitter";
|
|||||||
export * from "./cssNames";
|
export * from "./cssNames";
|
||||||
export * from "./cssVar";
|
export * from "./cssVar";
|
||||||
export * from "./display-booleans";
|
export * from "./display-booleans";
|
||||||
|
export * from "./display-mode";
|
||||||
export * from "./interval";
|
export * from "./interval";
|
||||||
export * from "./isMiddleClick";
|
export * from "./isMiddleClick";
|
||||||
export * from "./isReactNode";
|
export * from "./isReactNode";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user