mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge remote-tracking branch 'origin/master' into fix/catalog/icon_menu_option
# Conflicts: # src/renderer/components/+catalog/catalog.tsx
This commit is contained in:
commit
64765167eb
85
.eslintrc.js
85
.eslintrc.js
@ -31,18 +31,18 @@ module.exports = {
|
||||
settings: {
|
||||
react: {
|
||||
version: packageJson.devDependencies.react || "detect",
|
||||
}
|
||||
},
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
"**/*.js"
|
||||
"**/*.js",
|
||||
],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
],
|
||||
env: {
|
||||
node: true
|
||||
node: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
@ -51,32 +51,44 @@ module.exports = {
|
||||
plugins: [
|
||||
"header",
|
||||
"unused-imports",
|
||||
"react-hooks"
|
||||
"react-hooks",
|
||||
],
|
||||
rules: {
|
||||
"header/header": [2, "./license-header"],
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
"comma-spacing": "error",
|
||||
"indent": ["error", 2, {
|
||||
"SwitchCase": 1,
|
||||
}],
|
||||
"no-unused-vars": "off",
|
||||
"space-before-function-paren": ["error", {
|
||||
"anonymous": "always",
|
||||
"named": "never",
|
||||
"asyncArrow": "always",
|
||||
}],
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"warn", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true,
|
||||
}
|
||||
},
|
||||
],
|
||||
"quotes": ["error", "double", {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true,
|
||||
}],
|
||||
"object-curly-spacing": ["error", "always", {
|
||||
"objectsInObjects": false,
|
||||
"arraysInObjects": true,
|
||||
}],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"eol-last": ["error", "always"],
|
||||
"semi": ["error", "always"],
|
||||
"object-shorthand": "error",
|
||||
"prefer-template": "error",
|
||||
"template-curly-spacing": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"padding-line-between-statements": [
|
||||
"error",
|
||||
{ "blankLine": "always", "prev": "*", "next": "return" },
|
||||
@ -84,9 +96,10 @@ module.exports = {
|
||||
{ "blankLine": "always", "prev": "*", "next": "function" },
|
||||
{ "blankLine": "always", "prev": "*", "next": "class" },
|
||||
{ "blankLine": "always", "prev": ["const", "let", "var"], "next": "*" },
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]},
|
||||
]
|
||||
}
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] },
|
||||
],
|
||||
"no-template-curly-in-string": "error",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
@ -98,7 +111,7 @@ module.exports = {
|
||||
],
|
||||
plugins: [
|
||||
"header",
|
||||
"unused-imports"
|
||||
"unused-imports",
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
@ -115,14 +128,24 @@ module.exports = {
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"space-before-function-paren": "off",
|
||||
"@typescript-eslint/space-before-function-paren": ["error", {
|
||||
"anonymous": "always",
|
||||
"named": "never",
|
||||
"asyncArrow": "always",
|
||||
}],
|
||||
"unused-imports/no-unused-imports-ts": process.env.PROD === "true" ? "error" : "warn",
|
||||
"unused-imports/no-unused-vars-ts": [
|
||||
"warn", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true,
|
||||
}
|
||||
},
|
||||
],
|
||||
"comman-dangle": "off",
|
||||
"@typescript-eslint/comma-dangle": ["error", "always-multiline"],
|
||||
"comma-spacing": "off",
|
||||
"@typescript-eslint/comma-spacing": "error",
|
||||
"indent": ["error", 2, {
|
||||
"SwitchCase": 1,
|
||||
}],
|
||||
@ -130,6 +153,11 @@ module.exports = {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true,
|
||||
}],
|
||||
"object-curly-spacing": "off",
|
||||
"@typescript-eslint/object-curly-spacing": ["error", "always", {
|
||||
"objectsInObjects": false,
|
||||
"arraysInObjects": true,
|
||||
}],
|
||||
"react/prop-types": "off",
|
||||
"semi": "off",
|
||||
"@typescript-eslint/semi": ["error"],
|
||||
@ -138,6 +166,8 @@ module.exports = {
|
||||
"object-shorthand": "error",
|
||||
"prefer-template": "error",
|
||||
"template-curly-spacing": "error",
|
||||
"no-unused-expressions": "off",
|
||||
"@typescript-eslint/no-unused-expressions": "error",
|
||||
"padding-line-between-statements": [
|
||||
"error",
|
||||
{ "blankLine": "always", "prev": "*", "next": "return" },
|
||||
@ -145,8 +175,9 @@ module.exports = {
|
||||
{ "blankLine": "always", "prev": "*", "next": "function" },
|
||||
{ "blankLine": "always", "prev": "*", "next": "class" },
|
||||
{ "blankLine": "always", "prev": ["const", "let", "var"], "next": "*" },
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]},
|
||||
]
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] },
|
||||
],
|
||||
"no-template-curly-in-string": "error",
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -156,7 +187,7 @@ module.exports = {
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: [
|
||||
"header",
|
||||
"unused-imports"
|
||||
"unused-imports",
|
||||
],
|
||||
extends: [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
@ -183,14 +214,24 @@ module.exports = {
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"react/display-name": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"space-before-function-paren": "off",
|
||||
"@typescript-eslint/space-before-function-paren": ["error", {
|
||||
"anonymous": "always",
|
||||
"named": "never",
|
||||
"asyncArrow": "always",
|
||||
}],
|
||||
"unused-imports/no-unused-imports-ts": process.env.PROD === "true" ? "error" : "warn",
|
||||
"unused-imports/no-unused-vars-ts": [
|
||||
"warn", {
|
||||
"vars": "all",
|
||||
"args": "after-used",
|
||||
"ignoreRestSiblings": true,
|
||||
}
|
||||
},
|
||||
],
|
||||
"comman-dangle": "off",
|
||||
"@typescript-eslint/comma-dangle": ["error", "always-multiline"],
|
||||
"comma-spacing": "off",
|
||||
"@typescript-eslint/comma-spacing": "error",
|
||||
"indent": ["error", 2, {
|
||||
"SwitchCase": 1,
|
||||
}],
|
||||
@ -198,6 +239,11 @@ module.exports = {
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true,
|
||||
}],
|
||||
"object-curly-spacing": "off",
|
||||
"@typescript-eslint/object-curly-spacing": ["error", "always", {
|
||||
"objectsInObjects": false,
|
||||
"arraysInObjects": true,
|
||||
}],
|
||||
"react/prop-types": "off",
|
||||
"semi": "off",
|
||||
"@typescript-eslint/semi": ["error"],
|
||||
@ -206,6 +252,8 @@ module.exports = {
|
||||
"object-shorthand": "error",
|
||||
"prefer-template": "error",
|
||||
"template-curly-spacing": "error",
|
||||
"no-unused-expressions": "off",
|
||||
"@typescript-eslint/no-unused-expressions": "error",
|
||||
"padding-line-between-statements": [
|
||||
"error",
|
||||
{ "blankLine": "always", "prev": "*", "next": "return" },
|
||||
@ -213,11 +261,12 @@ module.exports = {
|
||||
{ "blankLine": "always", "prev": "*", "next": "function" },
|
||||
{ "blankLine": "always", "prev": "*", "next": "class" },
|
||||
{ "blankLine": "always", "prev": ["const", "let", "var"], "next": "*" },
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"]},
|
||||
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] },
|
||||
],
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
"react-hooks/exhaustive-deps": "off"
|
||||
"react-hooks/exhaustive-deps": "off",
|
||||
"no-template-curly-in-string": "error",
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
2
.yarnrc
2
.yarnrc
@ -1,3 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "13.6.0"
|
||||
target "13.6.1"
|
||||
runtime "electron"
|
||||
|
||||
2
Makefile
2
Makefile
@ -36,7 +36,7 @@ dev: binaries/client build-extensions static/build/LensDev.html
|
||||
yarn dev
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
lint: node_modules
|
||||
yarn lint
|
||||
|
||||
.PHONY: tag-release
|
||||
|
||||
@ -10,9 +10,9 @@ Lens releases are built by CICD automatically on git tags. The typical release p
|
||||
- `major`
|
||||
- `minor`
|
||||
- `patch`
|
||||
- `premajor` [--preid=<prerelease-id>]
|
||||
- `preminor` [--preid=<prerelease-id>]
|
||||
- `prepatch` [--preid=<prerelease-id>]
|
||||
- `premajor [--preid=<prerelease-id>]`
|
||||
- `preminor [--preid=<prerelease-id>]`
|
||||
- `prepatch [--preid=<prerelease-id>]`
|
||||
- `prerelease [--preid=<prerelease-id>]`
|
||||
|
||||
where `<prerelease-id>` is generally one of:
|
||||
@ -28,6 +28,8 @@ Lens releases are built by CICD automatically on git tags. The typical release p
|
||||
- `git tag -fa vX.Y.Z-beta.N` (move the tag locally to the current commit)
|
||||
- `git push origin --tags` (update the tags on https://github.com/lensapp/lens to reflect this local change)
|
||||
|
||||
Once the tag has been updated on origin (e.g. by `git push origin --tags`) the azure jobs are automatically triggered again.
|
||||
|
||||
1. Once CI passes again go to the releases tab on GitHub. You can use the existing draft release prepared by k8slens-bot (select the correct tag). Or you can create a new release from the tag that was created, and make sure that the change log is the same as that of the PR, and the title is the tag. Either way, click the prerelease checkbox if this is not a new major, minor, or patch version before clicking `Publish release`.
|
||||
1. Merge the release PR after the release is published. If it is a patch release then there is no need to squash the cherry-picked commits as part of the merge. GitHub should delete the branch once it is merged.
|
||||
1. If you have just released a new major or minor version then create a new `release/vMAJOR.MINOR` branch from that same tag and push it to https://github.com/lensapp/lens. Given the commit of the merged release PR from the master branch you can do this like
|
||||
|
||||
@ -28,6 +28,6 @@ export default {
|
||||
},
|
||||
dialog: jest.fn(),
|
||||
ipcRenderer: {
|
||||
on: jest.fn()
|
||||
}
|
||||
on: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
@ -28,7 +28,7 @@ const helmVersion = packageInfo.config.bundledHelmVersion;
|
||||
if (!isWindows) {
|
||||
Promise.all([
|
||||
new HelmCli(path.join(process.cwd(), "binaries", "client", "x64"), helmVersion).ensureBinary(),
|
||||
new HelmCli(path.join(process.cwd(), "binaries", "client", "arm64"), helmVersion).ensureBinary()
|
||||
new HelmCli(path.join(process.cwd(), "binaries", "client", "arm64"), helmVersion).ensureBinary(),
|
||||
]);
|
||||
} else {
|
||||
new HelmCli(path.join(process.cwd(), "binaries", "client", "x64"), helmVersion).ensureBinary();
|
||||
|
||||
@ -47,7 +47,7 @@ class KubectlDownloader {
|
||||
const response = await requestPromise({
|
||||
method: "HEAD",
|
||||
uri: this.url,
|
||||
resolveWithFullResponse: true
|
||||
resolveWithFullResponse: true,
|
||||
}).catch(console.error);
|
||||
|
||||
if (response.headers["etag"]) {
|
||||
@ -89,7 +89,7 @@ class KubectlDownloader {
|
||||
console.log(`Downloading kubectl ${this.kubectlVersion} from ${this.url} to ${this.path}`);
|
||||
const requestOpts: request.UriOptions & request.CoreOptions = {
|
||||
uri: this.url,
|
||||
gzip: true
|
||||
gzip: true,
|
||||
};
|
||||
const stream = request(requestOpts);
|
||||
|
||||
|
||||
@ -27,37 +27,37 @@ export default class EventResourceStatusRendererExtension extends Renderer.LensE
|
||||
{
|
||||
kind: "Pod",
|
||||
apiVersions: ["v1"],
|
||||
resolve: (pod: Renderer.K8sApi.Pod) => resolveStatusForPods(pod)
|
||||
resolve: (pod: Renderer.K8sApi.Pod) => resolveStatusForPods(pod),
|
||||
},
|
||||
{
|
||||
kind: "ReplicaSet",
|
||||
apiVersions: ["v1"],
|
||||
resolve: (replicaSet: Renderer.K8sApi.ReplicaSet) => resolveStatus(replicaSet)
|
||||
resolve: (replicaSet: Renderer.K8sApi.ReplicaSet) => resolveStatus(replicaSet),
|
||||
},
|
||||
{
|
||||
kind: "Deployment",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (deployment: Renderer.K8sApi.Deployment) => resolveStatus(deployment)
|
||||
resolve: (deployment: Renderer.K8sApi.Deployment) => resolveStatus(deployment),
|
||||
},
|
||||
{
|
||||
kind: "StatefulSet",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (statefulSet: Renderer.K8sApi.StatefulSet) => resolveStatus(statefulSet)
|
||||
resolve: (statefulSet: Renderer.K8sApi.StatefulSet) => resolveStatus(statefulSet),
|
||||
},
|
||||
{
|
||||
kind: "DaemonSet",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (daemonSet: Renderer.K8sApi.DaemonSet) => resolveStatus(daemonSet)
|
||||
resolve: (daemonSet: Renderer.K8sApi.DaemonSet) => resolveStatus(daemonSet),
|
||||
},
|
||||
{
|
||||
kind: "Job",
|
||||
apiVersions: ["batch/v1"],
|
||||
resolve: (job: Renderer.K8sApi.Job) => resolveStatus(job)
|
||||
resolve: (job: Renderer.K8sApi.Job) => resolveStatus(job),
|
||||
},
|
||||
{
|
||||
kind: "CronJob",
|
||||
apiVersions: ["batch/v1"],
|
||||
resolve: (cronJob: Renderer.K8sApi.CronJob) => resolveStatusForCronJobs(cronJob)
|
||||
resolve: (cronJob: Renderer.K8sApi.CronJob) => resolveStatusForCronJobs(cronJob),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export function resolveStatus(object: KubeObject): KubeObjectStatus {
|
||||
return {
|
||||
level: KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
timestamp: event.metadata.creationTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ export function resolveStatusForPods(pod: Pod): KubeObjectStatus {
|
||||
return {
|
||||
level: KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
timestamp: event.metadata.creationTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
@ -83,6 +83,6 @@ export function resolveStatusForCronJobs(cronJob: CronJob): KubeObjectStatus {
|
||||
return {
|
||||
level: KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
timestamp: event.metadata.creationTimestamp,
|
||||
};
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = [
|
||||
target: "electron-renderer",
|
||||
mode: "production",
|
||||
optimization: {
|
||||
minimize: false
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -43,8 +43,8 @@ module.exports = [
|
||||
"@k8slens/extensions": "var global.LensExtensions",
|
||||
"react": "var global.React",
|
||||
"mobx": "var global.Mobx",
|
||||
"mobx-react": "var global.MobxReact"
|
||||
}
|
||||
"mobx-react": "var global.MobxReact",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
extensions: [ ".tsx", ".ts", ".js" ],
|
||||
|
||||
@ -31,12 +31,12 @@ export default class ClusterMetricsFeatureExtension extends Renderer.LensExtensi
|
||||
title: "Lens Metrics",
|
||||
priority: 5,
|
||||
components: {
|
||||
View: ({ entity = null }: { entity: Common.Catalog.KubernetesCluster}) => {
|
||||
View: ({ entity = null }: { entity: Common.Catalog.KubernetesCluster }) => {
|
||||
return (
|
||||
<MetricsSettings cluster={entity} />
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -31,6 +31,13 @@ rules:
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
|
||||
@ -92,11 +92,11 @@ export class MetricsFeature {
|
||||
}
|
||||
|
||||
async getStatus(): Promise<MetricsStatus> {
|
||||
const status: MetricsStatus = { installed: false, canUpgrade: false};
|
||||
const status: MetricsStatus = { installed: false, canUpgrade: false };
|
||||
|
||||
try {
|
||||
const namespaceApi = forCluster(this.cluster, Namespace);
|
||||
const namespace = await namespaceApi.get({name: "lens-metrics"});
|
||||
const namespace = await namespaceApi.get({ name: "lens-metrics" });
|
||||
|
||||
if (namespace?.kind) {
|
||||
const currentVersion = namespace.metadata.annotations?.extensionVersion || "0.0.0";
|
||||
|
||||
@ -30,7 +30,7 @@ const {
|
||||
},
|
||||
Component: {
|
||||
SubTitle, FormSwitch, Switcher, Button,
|
||||
}
|
||||
},
|
||||
} = Renderer;
|
||||
|
||||
interface Props {
|
||||
@ -47,7 +47,7 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
@observable featureStates = {
|
||||
prometheus: false,
|
||||
kubeStateMetrics: false,
|
||||
nodeExporter: false
|
||||
nodeExporter: false,
|
||||
};
|
||||
@observable canUpgrade = false;
|
||||
@observable upgrading = false;
|
||||
@ -56,7 +56,7 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
|
||||
config: MetricsConfiguration = {
|
||||
prometheus: {
|
||||
enabled: false
|
||||
enabled: false,
|
||||
},
|
||||
persistence: {
|
||||
enabled: false,
|
||||
@ -114,7 +114,7 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
const statefulSet = forCluster(this.props.cluster, StatefulSet);
|
||||
|
||||
try {
|
||||
await statefulSet.get({name: "prometheus", namespace: "lens-metrics"});
|
||||
await statefulSet.get({ name: "prometheus", namespace: "lens-metrics" });
|
||||
this.featureStates.prometheus = true;
|
||||
} catch(e) {
|
||||
if (e?.error?.code === 404) {
|
||||
@ -127,7 +127,7 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
const deployment = forCluster(this.props.cluster, Deployment);
|
||||
|
||||
try {
|
||||
await deployment.get({name: "kube-state-metrics", namespace: "lens-metrics"});
|
||||
await deployment.get({ name: "kube-state-metrics", namespace: "lens-metrics" });
|
||||
this.featureStates.kubeStateMetrics = true;
|
||||
} catch(e) {
|
||||
if (e?.error?.code === 404) {
|
||||
@ -140,7 +140,7 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
const daemonSet = forCluster(this.props.cluster, DaemonSet);
|
||||
|
||||
try {
|
||||
await daemonSet.get({name: "node-exporter", namespace: "lens-metrics"});
|
||||
await daemonSet.get({ name: "node-exporter", namespace: "lens-metrics" });
|
||||
this.featureStates.nodeExporter = true;
|
||||
} catch(e) {
|
||||
if (e?.error?.code === 404) {
|
||||
@ -207,14 +207,14 @@ export class MetricsSettings extends React.Component<Props> {
|
||||
<>
|
||||
{ this.props.cluster.status.phase !== "connected" && (
|
||||
<section>
|
||||
<p style={ {color: "var(--colorError)"} }>
|
||||
<p style={ { color: "var(--colorError)" } }>
|
||||
Lens Metrics settings requires established connection to the cluster.
|
||||
</p>
|
||||
</section>
|
||||
)}
|
||||
{ !this.isActiveMetricsProvider && (
|
||||
<section>
|
||||
<p style={ {color: "var(--colorError)"} }>
|
||||
<p style={ { color: "var(--colorError)" } }>
|
||||
Other metrics provider is currently active. See "Metrics" tab for details.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = [
|
||||
target: "electron-renderer",
|
||||
mode: "production",
|
||||
optimization: {
|
||||
minimize: false
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -43,8 +43,8 @@ module.exports = [
|
||||
"@k8slens/extensions": "var global.LensExtensions",
|
||||
"react": "var global.React",
|
||||
"mobx": "var global.Mobx",
|
||||
"mobx-react": "var global.MobxReact"
|
||||
}
|
||||
"mobx-react": "var global.MobxReact",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
extensions: [ ".tsx", ".ts", ".js" ],
|
||||
@ -56,7 +56,7 @@ module.exports = [
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
},
|
||||
node: {
|
||||
__dirname: false
|
||||
}
|
||||
__dirname: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@ -29,8 +29,8 @@ export default class NodeMenuRendererExtension extends Renderer.LensExtension {
|
||||
kind: "Node",
|
||||
apiVersions: ["v1"],
|
||||
components: {
|
||||
MenuItem: (props: NodeMenuProps) => <NodeMenu {...props} />
|
||||
}
|
||||
}
|
||||
MenuItem: (props: NodeMenuProps) => <NodeMenu {...props} />,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { Renderer } from "@k8slens/extensions";
|
||||
import { Common, Renderer } from "@k8slens/extensions";
|
||||
|
||||
type Node = Renderer.K8sApi.Node;
|
||||
|
||||
@ -32,8 +32,11 @@ const {
|
||||
MenuItem,
|
||||
Icon,
|
||||
},
|
||||
Navigation
|
||||
Navigation,
|
||||
} = Renderer;
|
||||
const {
|
||||
App,
|
||||
} = Common;
|
||||
|
||||
|
||||
export interface NodeMenuProps extends Renderer.Component.KubeObjectMenuProps<Node> {
|
||||
@ -42,8 +45,12 @@ export interface NodeMenuProps extends Renderer.Component.KubeObjectMenuProps<No
|
||||
export function NodeMenu(props: NodeMenuProps) {
|
||||
const { object: node, toolbar } = props;
|
||||
|
||||
if (!node) return null;
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nodeName = node.getName();
|
||||
const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
|
||||
|
||||
const sendToTerminal = (command: string) => {
|
||||
terminalStore.sendCommand(command, {
|
||||
@ -62,15 +69,15 @@ export function NodeMenu(props: NodeMenuProps) {
|
||||
};
|
||||
|
||||
const cordon = () => {
|
||||
sendToTerminal(`kubectl cordon ${nodeName}`);
|
||||
sendToTerminal(`${kubectlPath} cordon ${nodeName}`);
|
||||
};
|
||||
|
||||
const unCordon = () => {
|
||||
sendToTerminal(`kubectl uncordon ${nodeName}`);
|
||||
sendToTerminal(`${kubectlPath} uncordon ${nodeName}`);
|
||||
};
|
||||
|
||||
const drain = () => {
|
||||
const command = `kubectl drain ${nodeName} --delete-local-data --ignore-daemonsets --force`;
|
||||
const command = `${kubectlPath} drain ${nodeName} --delete-local-data --ignore-daemonsets --force`;
|
||||
|
||||
ConfirmDialog.open({
|
||||
ok: () => sendToTerminal(command),
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = [
|
||||
target: "electron-renderer",
|
||||
mode: "production",
|
||||
optimization: {
|
||||
minimize: false
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -43,8 +43,8 @@ module.exports = [
|
||||
"@k8slens/extensions": "var global.LensExtensions",
|
||||
"react": "var global.React",
|
||||
"mobx": "var global.Mobx",
|
||||
"mobx-react": "var global.MobxReact"
|
||||
}
|
||||
"mobx-react": "var global.MobxReact",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
extensions: [ ".tsx", ".ts", ".js" ],
|
||||
|
||||
@ -31,22 +31,22 @@ export default class PodMenuRendererExtension extends Renderer.LensExtension {
|
||||
kind: "Pod",
|
||||
apiVersions: ["v1"],
|
||||
components: {
|
||||
MenuItem: (props: PodAttachMenuProps) => <PodAttachMenu {...props} />
|
||||
}
|
||||
MenuItem: (props: PodAttachMenuProps) => <PodAttachMenu {...props} />,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Pod",
|
||||
apiVersions: ["v1"],
|
||||
components: {
|
||||
MenuItem: (props: PodShellMenuProps) => <PodShellMenu {...props} />
|
||||
}
|
||||
MenuItem: (props: PodShellMenuProps) => <PodShellMenu {...props} />,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind: "Pod",
|
||||
apiVersions: ["v1"],
|
||||
components: {
|
||||
MenuItem: (props: PodLogsMenuProps) => <PodLogsMenu {...props} />
|
||||
}
|
||||
}
|
||||
MenuItem: (props: PodLogsMenuProps) => <PodLogsMenu {...props} />,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@ const {
|
||||
} = Renderer;
|
||||
const {
|
||||
Util,
|
||||
App,
|
||||
} = Common;
|
||||
|
||||
export interface PodAttachMenuProps extends Renderer.Component.KubeObjectMenuProps<Pod> {
|
||||
@ -47,22 +48,34 @@ export interface PodAttachMenuProps extends Renderer.Component.KubeObjectMenuPro
|
||||
export class PodAttachMenu extends React.Component<PodAttachMenuProps> {
|
||||
async attachToPod(container?: string) {
|
||||
const { object: pod } = this.props;
|
||||
const containerParam = container ? `-c ${container}` : "";
|
||||
let command = `kubectl attach -i -t -n ${pod.getNs()} ${pod.getName()} ${containerParam}`;
|
||||
|
||||
const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
|
||||
const commandParts = [
|
||||
kubectlPath,
|
||||
"attach",
|
||||
"-i",
|
||||
"-t",
|
||||
"-n", pod.getNs(),
|
||||
pod.getName(),
|
||||
];
|
||||
|
||||
if (window.navigator.platform !== "Win32") {
|
||||
command = `exec ${command}`;
|
||||
commandParts.unshift("exec");
|
||||
}
|
||||
|
||||
if (container) {
|
||||
commandParts.push("-c", container);
|
||||
}
|
||||
|
||||
const shell = createTerminalTab({
|
||||
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()}) [Attached]`
|
||||
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()}) [Attached]`,
|
||||
});
|
||||
|
||||
terminalStore.sendCommand(command, {
|
||||
terminalStore.sendCommand(commandParts.join(" "), {
|
||||
enter: true,
|
||||
tabId: shell.id
|
||||
tabId: shell.id,
|
||||
});
|
||||
|
||||
|
||||
Navigation.hideDetails();
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ const {
|
||||
} = Renderer;
|
||||
const {
|
||||
Util,
|
||||
App,
|
||||
} = Common;
|
||||
|
||||
export interface PodShellMenuProps extends Renderer.Component.KubeObjectMenuProps<Pod> {
|
||||
@ -46,29 +47,44 @@ export interface PodShellMenuProps extends Renderer.Component.KubeObjectMenuProp
|
||||
|
||||
export class PodShellMenu extends React.Component<PodShellMenuProps> {
|
||||
async execShell(container?: string) {
|
||||
Navigation.hideDetails();
|
||||
const { object: pod } = this.props;
|
||||
const containerParam = container ? `-c ${container}` : "";
|
||||
let command = `kubectl exec -i -t -n ${pod.getNs()} ${pod.getName()} ${containerParam} "--"`;
|
||||
|
||||
const kubectlPath = App.Preferences.getKubectlPath() || "kubectl";
|
||||
const commandParts = [
|
||||
kubectlPath,
|
||||
"exec",
|
||||
"-i",
|
||||
"-t",
|
||||
"-n", pod.getNs(),
|
||||
pod.getName(),
|
||||
];
|
||||
|
||||
if (window.navigator.platform !== "Win32") {
|
||||
command = `exec ${command}`;
|
||||
commandParts.unshift("exec");
|
||||
}
|
||||
|
||||
if (container) {
|
||||
commandParts.push("-c", container);
|
||||
}
|
||||
|
||||
commandParts.push("--");
|
||||
|
||||
if (pod.getSelectedNodeOs() === "windows") {
|
||||
command = `${command} powershell`;
|
||||
commandParts.push("powershell");
|
||||
} else {
|
||||
command = `${command} sh -c "clear; (bash || ash || sh)"`;
|
||||
commandParts.push('sh -c "clear; (bash || ash || sh)"');
|
||||
}
|
||||
|
||||
const shell = createTerminalTab({
|
||||
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`
|
||||
title: `Pod: ${pod.getName()} (namespace: ${pod.getNs()})`,
|
||||
});
|
||||
|
||||
terminalStore.sendCommand(command, {
|
||||
terminalStore.sendCommand(commandParts.join(" "), {
|
||||
enter: true,
|
||||
tabId: shell.id
|
||||
tabId: shell.id,
|
||||
});
|
||||
|
||||
Navigation.hideDetails();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@ -27,7 +27,7 @@ module.exports = [
|
||||
target: "electron-renderer",
|
||||
mode: "production",
|
||||
optimization: {
|
||||
minimize: false
|
||||
minimize: false,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -43,8 +43,8 @@ module.exports = [
|
||||
"@k8slens/extensions": "var global.LensExtensions",
|
||||
"react": "var global.React",
|
||||
"mobx": "var global.Mobx",
|
||||
"mobx-react": "var global.MobxReact"
|
||||
}
|
||||
"mobx-react": "var global.MobxReact",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
extensions: [ ".tsx", ".ts", ".js" ],
|
||||
|
||||
@ -75,16 +75,16 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Cluster",
|
||||
href: "/overview",
|
||||
expectedSelector: "div[data-testid='cluster-overview-page'] div.label",
|
||||
expectedText: "CPU"
|
||||
}
|
||||
expectedText: "CPU",
|
||||
},
|
||||
},
|
||||
{
|
||||
page: {
|
||||
name: "Nodes",
|
||||
href: "/nodes",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Nodes"
|
||||
}
|
||||
expectedText: "Nodes",
|
||||
},
|
||||
},
|
||||
{
|
||||
drawerId: "workloads",
|
||||
@ -93,51 +93,51 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Overview",
|
||||
href: "/workloads",
|
||||
expectedSelector: "h5.box",
|
||||
expectedText: "Overview"
|
||||
expectedText: "Overview",
|
||||
},
|
||||
{
|
||||
name: "Pods",
|
||||
href: "/pods",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Pods"
|
||||
expectedText: "Pods",
|
||||
},
|
||||
{
|
||||
name: "Deployments",
|
||||
href: "/deployments",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Deployments"
|
||||
expectedText: "Deployments",
|
||||
},
|
||||
{
|
||||
name: "DaemonSets",
|
||||
href: "/daemonsets",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Daemon Sets"
|
||||
expectedText: "Daemon Sets",
|
||||
},
|
||||
{
|
||||
name: "StatefulSets",
|
||||
href: "/statefulsets",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Stateful Sets"
|
||||
expectedText: "Stateful Sets",
|
||||
},
|
||||
{
|
||||
name: "ReplicaSets",
|
||||
href: "/replicasets",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Replica Sets"
|
||||
expectedText: "Replica Sets",
|
||||
},
|
||||
{
|
||||
name: "Jobs",
|
||||
href: "/jobs",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Jobs"
|
||||
expectedText: "Jobs",
|
||||
},
|
||||
{
|
||||
name: "CronJobs",
|
||||
href: "/cronjobs",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Cron Jobs"
|
||||
expectedText: "Cron Jobs",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
drawerId: "config",
|
||||
@ -146,39 +146,39 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "ConfigMaps",
|
||||
href: "/configmaps",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Config Maps"
|
||||
expectedText: "Config Maps",
|
||||
},
|
||||
{
|
||||
name: "Secrets",
|
||||
href: "/secrets",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Secrets"
|
||||
expectedText: "Secrets",
|
||||
},
|
||||
{
|
||||
name: "Resource Quotas",
|
||||
href: "/resourcequotas",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Resource Quotas"
|
||||
expectedText: "Resource Quotas",
|
||||
},
|
||||
{
|
||||
name: "Limit Ranges",
|
||||
href: "/limitranges",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Limit Ranges"
|
||||
expectedText: "Limit Ranges",
|
||||
},
|
||||
{
|
||||
name: "HPA",
|
||||
href: "/hpa",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Horizontal Pod Autoscalers"
|
||||
expectedText: "Horizontal Pod Autoscalers",
|
||||
},
|
||||
{
|
||||
name: "Pod Disruption Budgets",
|
||||
href: "/poddisruptionbudgets",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Pod Disruption Budgets"
|
||||
expectedText: "Pod Disruption Budgets",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
drawerId: "networks",
|
||||
@ -187,27 +187,27 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Services",
|
||||
href: "/services",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Services"
|
||||
expectedText: "Services",
|
||||
},
|
||||
{
|
||||
name: "Endpoints",
|
||||
href: "/endpoints",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Endpoints"
|
||||
expectedText: "Endpoints",
|
||||
},
|
||||
{
|
||||
name: "Ingresses",
|
||||
href: "/ingresses",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Ingresses"
|
||||
expectedText: "Ingresses",
|
||||
},
|
||||
{
|
||||
name: "Network Policies",
|
||||
href: "/network-policies",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Network Policies"
|
||||
expectedText: "Network Policies",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
drawerId: "storage",
|
||||
@ -216,37 +216,37 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Persistent Volume Claims",
|
||||
href: "/persistent-volume-claims",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Persistent Volume Claims"
|
||||
expectedText: "Persistent Volume Claims",
|
||||
},
|
||||
{
|
||||
name: "Persistent Volumes",
|
||||
href: "/persistent-volumes",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Persistent Volumes"
|
||||
expectedText: "Persistent Volumes",
|
||||
},
|
||||
{
|
||||
name: "Storage Classes",
|
||||
href: "/storage-classes",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Storage Classes"
|
||||
expectedText: "Storage Classes",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
page: {
|
||||
name: "Namespaces",
|
||||
href: "/namespaces",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Namespaces"
|
||||
}
|
||||
expectedText: "Namespaces",
|
||||
},
|
||||
},
|
||||
{
|
||||
page: {
|
||||
name: "Events",
|
||||
href: "/events",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Events"
|
||||
}
|
||||
expectedText: "Events",
|
||||
},
|
||||
},
|
||||
{
|
||||
drawerId: "apps",
|
||||
@ -260,9 +260,9 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Releases",
|
||||
href: "/apps/releases",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Releases"
|
||||
expectedText: "Releases",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
drawerId: "users",
|
||||
@ -271,39 +271,39 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Service Accounts",
|
||||
href: "/service-accounts",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Service Accounts"
|
||||
expectedText: "Service Accounts",
|
||||
},
|
||||
{
|
||||
name: "Roles",
|
||||
href: "/roles",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Roles"
|
||||
expectedText: "Roles",
|
||||
},
|
||||
{
|
||||
name: "Cluster Roles",
|
||||
href: "/cluster-roles",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Cluster Roles"
|
||||
expectedText: "Cluster Roles",
|
||||
},
|
||||
{
|
||||
name: "Role Bindings",
|
||||
href: "/role-bindings",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Role Bindings"
|
||||
expectedText: "Role Bindings",
|
||||
},
|
||||
{
|
||||
name: "Cluster Role Bindings",
|
||||
href: "/cluster-role-bindings",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Cluster Role Bindings"
|
||||
expectedText: "Cluster Role Bindings",
|
||||
},
|
||||
{
|
||||
name: "Pod Security Policies",
|
||||
href: "/pod-security-policies",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Pod Security Policies"
|
||||
expectedText: "Pod Security Policies",
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
drawerId: "custom-resources",
|
||||
@ -312,9 +312,9 @@ const commonPageTests: CommonPageTest[] = [{
|
||||
name: "Definitions",
|
||||
href: "/crd/definitions",
|
||||
expectedSelector: "h5.title",
|
||||
expectedText: "Custom Resources"
|
||||
expectedText: "Custom Resources",
|
||||
},
|
||||
]
|
||||
],
|
||||
}];
|
||||
|
||||
utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
|
||||
@ -440,7 +440,7 @@ utils.describeIf(minikubeReady(TEST_NAMESPACE))("Minikube based tests", () => {
|
||||
position: {
|
||||
y: 0,
|
||||
x: 0,
|
||||
}
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
@ -69,7 +69,7 @@ export async function start() {
|
||||
bypassCSP: true,
|
||||
env: {
|
||||
CICD,
|
||||
...process.env
|
||||
...process.env,
|
||||
},
|
||||
timeout: 100_000,
|
||||
} as Parameters<typeof electron["launch"]>[0]);
|
||||
|
||||
37
package.json
37
package.json
@ -3,7 +3,7 @@
|
||||
"productName": "OpenLens",
|
||||
"description": "OpenLens - Open Source IDE for Kubernetes",
|
||||
"homepage": "https://github.com/lensapp/lens",
|
||||
"version": "5.3.0-alpha.6",
|
||||
"version": "5.3.0-alpha.8",
|
||||
"main": "static/build/main.js",
|
||||
"copyright": "© 2021 OpenLens Authors",
|
||||
"license": "MIT",
|
||||
@ -196,7 +196,7 @@
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-updater": "^4.6.1",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"filehound": "^1.17.4",
|
||||
"filehound": "^1.17.5",
|
||||
"fs-extra": "^9.0.1",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"got": "^11.8.2",
|
||||
@ -214,12 +214,12 @@
|
||||
"md5-file": "^5.0.0",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-observable-history": "^2.0.1",
|
||||
"mobx-react": "^7.2.0",
|
||||
"mobx-react": "^7.2.1",
|
||||
"mock-fs": "^4.14.0",
|
||||
"moment": "^2.29.1",
|
||||
"moment-timezone": "^0.5.33",
|
||||
"monaco-editor": "^0.26.1",
|
||||
"node-fetch": "^2.6.5",
|
||||
"node-fetch": "^2.6.6",
|
||||
"node-pty": "^0.10.1",
|
||||
"npm": "^6.14.15",
|
||||
"p-limit": "^3.1.0",
|
||||
@ -255,9 +255,8 @@
|
||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||
"@sentry/types": "^6.13.3",
|
||||
"@testing-library/dom": "^8.9.0",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.6",
|
||||
"@testing-library/jest-dom": "^5.15.0",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/byline": "^4.2.33",
|
||||
"@types/chart.js": "^2.9.34",
|
||||
@ -285,10 +284,10 @@
|
||||
"@types/progress-bar-webpack-plugin": "^2.1.2",
|
||||
"@types/proper-lockfile": "^4.1.2",
|
||||
"@types/randomcolor": "^0.5.6",
|
||||
"@types/react": "^17.0.29",
|
||||
"@types/react": "^17.0.33",
|
||||
"@types/react-beautiful-dnd": "^13.1.2",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/react-router-dom": "^5.3.1",
|
||||
"@types/react-router-dom": "^5.3.2",
|
||||
"@types/react-select": "3.1.2",
|
||||
"@types/react-table": "^7.7.7",
|
||||
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
||||
@ -296,9 +295,9 @@
|
||||
"@types/readable-stream": "^2.3.11",
|
||||
"@types/request": "^2.48.7",
|
||||
"@types/request-promise-native": "^1.0.18",
|
||||
"@types/semver": "^7.2.0",
|
||||
"@types/semver": "^7.3.9",
|
||||
"@types/sharp": "^0.29.2",
|
||||
"@types/spdy": "^3.4.4",
|
||||
"@types/spdy": "^3.4.5",
|
||||
"@types/tar": "^4.0.5",
|
||||
"@types/tcp-port-used": "^1.0.0",
|
||||
"@types/tempy": "^0.3.0",
|
||||
@ -310,7 +309,7 @@
|
||||
"@types/webpack-env": "^1.16.3",
|
||||
"@types/webpack-node-externals": "^1.7.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||
"@typescript-eslint/parser": "^4.29.1",
|
||||
"@typescript-eslint/parser": "^4.33.0",
|
||||
"ansi_up": "^5.0.1",
|
||||
"chart.js": "^2.9.4",
|
||||
"circular-dependency-plugin": "^5.2.2",
|
||||
@ -319,7 +318,7 @@
|
||||
"css-loader": "^5.2.7",
|
||||
"deepdash": "^5.3.9",
|
||||
"dompurify": "^2.3.3",
|
||||
"electron": "13.6.0",
|
||||
"electron": "^13.6.1",
|
||||
"electron-builder": "^22.11.11",
|
||||
"electron-notarize": "^0.3.0",
|
||||
"esbuild": "^0.13.8",
|
||||
@ -345,7 +344,7 @@
|
||||
"node-loader": "^1.0.3",
|
||||
"nodemon": "^2.0.14",
|
||||
"playwright": "^1.15.2",
|
||||
"postcss": "^8.3.6",
|
||||
"postcss": "^8.3.11",
|
||||
"postcss-loader": "4.3.0",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"progress-bar-webpack-plugin": "^2.1.0",
|
||||
@ -357,17 +356,17 @@
|
||||
"react-select": "3.2.0",
|
||||
"react-select-event": "^5.1.0",
|
||||
"react-table": "^7.7.0",
|
||||
"react-window": "^1.8.5",
|
||||
"sass": "^1.43.2",
|
||||
"react-window": "^1.8.6",
|
||||
"sass": "^1.43.4",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sharp": "^0.29.2",
|
||||
"style-loader": "^2.0.0",
|
||||
"tailwindcss": "^2.2.17",
|
||||
"ts-jest": "26.5.6",
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-node": "^10.3.0",
|
||||
"ts-node": "^10.4.0",
|
||||
"type-fest": "^1.0.2",
|
||||
"typed-emitter": "^1.3.1",
|
||||
"typed-emitter": "^1.4.0",
|
||||
"typedoc": "0.22.7",
|
||||
"typedoc-plugin-markdown": "^3.11.3",
|
||||
"typeface-roboto": "^1.1.13",
|
||||
@ -379,7 +378,7 @@
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"what-input": "^5.2.10",
|
||||
"xterm": "^4.12.0",
|
||||
"xterm": "^4.14.1",
|
||||
"xterm-addon-fit": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,8 +34,8 @@ class TestCatalogCategory extends CatalogCategory {
|
||||
group: "entity.k8slens.dev",
|
||||
versions: [],
|
||||
names: {
|
||||
kind: "Test"
|
||||
}
|
||||
kind: "Test",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -50,8 +50,8 @@ class TestCatalogCategory2 extends CatalogCategory {
|
||||
group: "entity.k8slens.dev",
|
||||
versions: [],
|
||||
names: {
|
||||
kind: "Test2"
|
||||
}
|
||||
kind: "Test2",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ jest.mock("electron", () => ({
|
||||
removeAllListeners: jest.fn(),
|
||||
off: jest.fn(),
|
||||
send: jest.fn(),
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
AppPaths.init();
|
||||
@ -95,8 +95,8 @@ describe("empty config", () => {
|
||||
ClusterStore.resetInstance();
|
||||
const mockOpts = {
|
||||
"tmp": {
|
||||
"lens-cluster-store.json": JSON.stringify({})
|
||||
}
|
||||
"lens-cluster-store.json": JSON.stringify({}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -117,10 +117,10 @@ describe("empty config", () => {
|
||||
preferences: {
|
||||
terminalCWD: "/tmp",
|
||||
icon: "data:image/jpeg;base64, iVBORw0KGgoAAAANSUhEUgAAA1wAAAKoCAYAAABjkf5",
|
||||
clusterName: "minikube"
|
||||
clusterName: "minikube",
|
||||
},
|
||||
kubeConfigPath: embed("foo", kubeconfig)
|
||||
})
|
||||
kubeConfigPath: embed("foo", kubeconfig),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@ -141,17 +141,17 @@ describe("empty config", () => {
|
||||
id: "prod",
|
||||
contextName: "foo",
|
||||
preferences: {
|
||||
clusterName: "prod"
|
||||
clusterName: "prod",
|
||||
},
|
||||
kubeConfigPath: embed("prod", kubeconfig)
|
||||
kubeConfigPath: embed("prod", kubeconfig),
|
||||
});
|
||||
store.addCluster({
|
||||
id: "dev",
|
||||
contextName: "foo2",
|
||||
preferences: {
|
||||
clusterName: "dev"
|
||||
clusterName: "dev",
|
||||
},
|
||||
kubeConfigPath: embed("dev", kubeconfig)
|
||||
kubeConfigPath: embed("dev", kubeconfig),
|
||||
});
|
||||
});
|
||||
|
||||
@ -177,8 +177,8 @@ describe("config with existing clusters", () => {
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "99.99.99"
|
||||
}
|
||||
version: "99.99.99",
|
||||
},
|
||||
},
|
||||
clusters: [
|
||||
{
|
||||
@ -186,13 +186,13 @@ describe("config with existing clusters", () => {
|
||||
kubeConfigPath: "./temp-kube-config",
|
||||
contextName: "foo",
|
||||
preferences: { terminalCWD: "/foo" },
|
||||
workspace: "default"
|
||||
workspace: "default",
|
||||
},
|
||||
{
|
||||
id: "cluster2",
|
||||
kubeConfigPath: "./temp-kube-config",
|
||||
contextName: "foo2",
|
||||
preferences: { terminalCWD: "/foo2" }
|
||||
preferences: { terminalCWD: "/foo2" },
|
||||
},
|
||||
{
|
||||
id: "cluster3",
|
||||
@ -200,11 +200,11 @@ describe("config with existing clusters", () => {
|
||||
contextName: "foo",
|
||||
preferences: { terminalCWD: "/foo" },
|
||||
workspace: "foo",
|
||||
ownerRef: "foo"
|
||||
ownerRef: "foo",
|
||||
},
|
||||
]
|
||||
})
|
||||
}
|
||||
],
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -265,8 +265,8 @@ users:
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "99.99.99"
|
||||
}
|
||||
version: "99.99.99",
|
||||
},
|
||||
},
|
||||
clusters: [
|
||||
{
|
||||
@ -281,12 +281,12 @@ users:
|
||||
kubeConfigPath: "./valid-kube-config",
|
||||
contextName: "foo",
|
||||
preferences: { terminalCWD: "/foo" },
|
||||
workspace: "default"
|
||||
workspace: "default",
|
||||
},
|
||||
|
||||
]
|
||||
})
|
||||
}
|
||||
],
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -326,7 +326,7 @@ const minimalValidKubeConfig = JSON.stringify({
|
||||
user: {
|
||||
"client-certificate": "/Users/foo/.minikube/client.crt",
|
||||
"client-key": "/Users/foo/.minikube/client.key",
|
||||
}
|
||||
},
|
||||
}],
|
||||
kind: "Config",
|
||||
preferences: {},
|
||||
@ -340,12 +340,12 @@ describe("pre 2.0 config with an existing cluster", () => {
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "1.0.0"
|
||||
}
|
||||
version: "1.0.0",
|
||||
},
|
||||
},
|
||||
cluster1: minimalValidKubeConfig,
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -372,8 +372,8 @@ describe("pre 2.6.0 config with a cluster that has arrays in auth config", () =>
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "2.4.1"
|
||||
}
|
||||
version: "2.4.1",
|
||||
},
|
||||
},
|
||||
cluster1: {
|
||||
kubeConfig: JSON.stringify({
|
||||
@ -403,19 +403,19 @@ describe("pre 2.6.0 config with a cluster that has arrays in auth config", () =>
|
||||
"auth-provider": {
|
||||
config: {
|
||||
"access-token": [
|
||||
"should be string"
|
||||
"should be string",
|
||||
],
|
||||
expiry: [
|
||||
"should be string"
|
||||
"should be string",
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}]
|
||||
}],
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -445,19 +445,19 @@ describe("pre 2.6.0 config with a cluster icon", () => {
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "2.4.1"
|
||||
}
|
||||
version: "2.4.1",
|
||||
},
|
||||
},
|
||||
cluster1: {
|
||||
kubeConfig: minimalValidKubeConfig,
|
||||
icon: "icon_path",
|
||||
preferences: {
|
||||
terminalCWD: "/tmp"
|
||||
}
|
||||
terminalCWD: "/tmp",
|
||||
},
|
||||
},
|
||||
}),
|
||||
"icon_path": testDataIcon,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -486,17 +486,17 @@ describe("for a pre 2.7.0-beta.0 config without a workspace", () => {
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "2.6.6"
|
||||
}
|
||||
version: "2.6.6",
|
||||
},
|
||||
},
|
||||
cluster1: {
|
||||
kubeConfig: minimalValidKubeConfig,
|
||||
preferences: {
|
||||
terminalCWD: "/tmp"
|
||||
}
|
||||
terminalCWD: "/tmp",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -517,8 +517,8 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "3.5.0"
|
||||
}
|
||||
version: "3.5.0",
|
||||
},
|
||||
},
|
||||
clusters: [
|
||||
{
|
||||
@ -527,12 +527,12 @@ describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
|
||||
contextName: "cluster",
|
||||
preferences: {
|
||||
icon: "store://icon_path",
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
"icon_path": testDataIcon,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
|
||||
@ -34,7 +34,7 @@ describe("event bus tests", () => {
|
||||
event = data;
|
||||
});
|
||||
|
||||
appEventBus.emit({name: "foo", action: "bar"});
|
||||
appEventBus.emit({ name: "foo", action: "bar" });
|
||||
expect(event.name).toBe("foo");
|
||||
});
|
||||
});
|
||||
|
||||
@ -33,25 +33,25 @@ jest.mock("../../main/catalog/catalog-entity-registry", () => ({
|
||||
metadata: {
|
||||
uid: "1dfa26e2ebab15780a3547e9c7fa785c",
|
||||
name: "mycluster",
|
||||
source: "local"
|
||||
}
|
||||
source: "local",
|
||||
},
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
uid: "55b42c3c7ba3b04193416cda405269a5",
|
||||
name: "my_shiny_cluster",
|
||||
source: "remote"
|
||||
}
|
||||
source: "remote",
|
||||
},
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
uid: "catalog-entity",
|
||||
name: "Catalog",
|
||||
source: "app"
|
||||
source: "app",
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
const testCluster = {
|
||||
@ -60,7 +60,7 @@ const testCluster = {
|
||||
apiVersion: "v1",
|
||||
kind: "Cluster",
|
||||
status: {
|
||||
phase: "Running"
|
||||
phase: "Running",
|
||||
},
|
||||
spec: {},
|
||||
getName: jest.fn(),
|
||||
@ -71,8 +71,8 @@ const testCluster = {
|
||||
metadata: {
|
||||
uid: "test",
|
||||
name: "test",
|
||||
labels: {}
|
||||
}
|
||||
labels: {},
|
||||
},
|
||||
};
|
||||
|
||||
const minikubeCluster = {
|
||||
@ -81,7 +81,7 @@ const minikubeCluster = {
|
||||
apiVersion: "v1",
|
||||
kind: "Cluster",
|
||||
status: {
|
||||
phase: "Running"
|
||||
phase: "Running",
|
||||
},
|
||||
spec: {},
|
||||
getName: jest.fn(),
|
||||
@ -92,8 +92,8 @@ const minikubeCluster = {
|
||||
metadata: {
|
||||
uid: "minikube",
|
||||
name: "minikube",
|
||||
labels: {}
|
||||
}
|
||||
labels: {},
|
||||
},
|
||||
};
|
||||
|
||||
const awsCluster = {
|
||||
@ -102,7 +102,7 @@ const awsCluster = {
|
||||
apiVersion: "v1",
|
||||
kind: "Cluster",
|
||||
status: {
|
||||
phase: "Running"
|
||||
phase: "Running",
|
||||
},
|
||||
spec: {},
|
||||
getName: jest.fn(),
|
||||
@ -113,8 +113,8 @@ const awsCluster = {
|
||||
metadata: {
|
||||
uid: "aws",
|
||||
name: "aws",
|
||||
labels: {}
|
||||
}
|
||||
labels: {},
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock("electron", () => ({
|
||||
@ -139,8 +139,8 @@ describe("HotbarStore", () => {
|
||||
beforeEach(() => {
|
||||
mockFs({
|
||||
"tmp": {
|
||||
"lens-hotbar-store.json": JSON.stringify({})
|
||||
}
|
||||
"lens-hotbar-store.json": JSON.stringify({}),
|
||||
},
|
||||
});
|
||||
ClusterStore.createInstance();
|
||||
HotbarStore.createInstance();
|
||||
@ -351,8 +351,8 @@ describe("HotbarStore", () => {
|
||||
"lens-hotbar-store.json": JSON.stringify({
|
||||
__internal__: {
|
||||
migrations: {
|
||||
version: "5.0.0-beta.3"
|
||||
}
|
||||
version: "5.0.0-beta.3",
|
||||
},
|
||||
},
|
||||
"hotbars": [
|
||||
{
|
||||
@ -361,51 +361,51 @@ describe("HotbarStore", () => {
|
||||
"items": [
|
||||
{
|
||||
"entity": {
|
||||
"uid": "1dfa26e2ebab15780a3547e9c7fa785c"
|
||||
}
|
||||
"uid": "1dfa26e2ebab15780a3547e9c7fa785c",
|
||||
},
|
||||
},
|
||||
{
|
||||
"entity": {
|
||||
"uid": "55b42c3c7ba3b04193416cda405269a5"
|
||||
}
|
||||
"uid": "55b42c3c7ba3b04193416cda405269a5",
|
||||
},
|
||||
},
|
||||
{
|
||||
"entity": {
|
||||
"uid": "176fd331968660832f62283219d7eb6e"
|
||||
}
|
||||
"uid": "176fd331968660832f62283219d7eb6e",
|
||||
},
|
||||
},
|
||||
{
|
||||
"entity": {
|
||||
"uid": "61c4fb45528840ebad1badc25da41d14",
|
||||
"name": "user1-context",
|
||||
"source": "local"
|
||||
}
|
||||
"source": "local",
|
||||
},
|
||||
},
|
||||
{
|
||||
"entity": {
|
||||
"uid": "27d6f99fe9e7548a6e306760bfe19969",
|
||||
"name": "foo2",
|
||||
"source": "local"
|
||||
}
|
||||
"source": "local",
|
||||
},
|
||||
},
|
||||
null,
|
||||
{
|
||||
"entity": {
|
||||
"uid": "c0b20040646849bb4dcf773e43a0bf27",
|
||||
"name": "multinode-demo",
|
||||
"source": "local"
|
||||
}
|
||||
"source": "local",
|
||||
},
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
]
|
||||
}
|
||||
null,
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
mockFs(mockOpts);
|
||||
@ -436,16 +436,16 @@ describe("HotbarStore", () => {
|
||||
entity: {
|
||||
name: "mycluster",
|
||||
source: "local",
|
||||
uid: "1dfa26e2ebab15780a3547e9c7fa785c"
|
||||
}
|
||||
uid: "1dfa26e2ebab15780a3547e9c7fa785c",
|
||||
},
|
||||
});
|
||||
|
||||
expect(items[1]).toEqual({
|
||||
entity: {
|
||||
name: "my_shiny_cluster",
|
||||
source: "remote",
|
||||
uid: "55b42c3c7ba3b04193416cda405269a5"
|
||||
}
|
||||
uid: "55b42c3c7ba3b04193416cda405269a5",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -100,7 +100,7 @@ describe("kube helpers", () => {
|
||||
describe("with invalid context object", () => {
|
||||
it("returns an error", () => {
|
||||
expect(String(validateKubeConfig(kc, "invalid"))).toEqual(
|
||||
expect.stringContaining("No valid context object provided in kubeconfig for context 'invalid'")
|
||||
expect.stringContaining("No valid context object provided in kubeconfig for context 'invalid'"),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -108,7 +108,7 @@ describe("kube helpers", () => {
|
||||
describe("with invalid cluster object", () => {
|
||||
it("returns an error", () => {
|
||||
expect(String(validateKubeConfig(kc, "invalidCluster"))).toEqual(
|
||||
expect.stringContaining("No valid cluster object provided in kubeconfig for context 'invalidCluster'")
|
||||
expect.stringContaining("No valid cluster object provided in kubeconfig for context 'invalidCluster'"),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -116,7 +116,7 @@ describe("kube helpers", () => {
|
||||
describe("with invalid user object", () => {
|
||||
it("returns an error", () => {
|
||||
expect(String(validateKubeConfig(kc, "invalidUser"))).toEqual(
|
||||
expect.stringContaining("No valid user object provided in kubeconfig for context 'invalidUser'")
|
||||
expect.stringContaining("No valid user object provided in kubeconfig for context 'invalidUser'"),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -174,7 +174,7 @@ describe("kube helpers", () => {
|
||||
});
|
||||
|
||||
it("multiple context is ok", async () => {
|
||||
mockKubeConfig.contexts.push({context: {cluster: "cluster-2", user: "cluster-2"}, name: "cluster-2"});
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "cluster-2", user: "cluster-2" }, name: "cluster-2" });
|
||||
const { config } = loadConfigFromString(JSON.stringify(mockKubeConfig));
|
||||
|
||||
expect(config.getCurrentContext()).toBe("minikube");
|
||||
@ -209,7 +209,7 @@ describe("kube helpers", () => {
|
||||
});
|
||||
|
||||
it("empty name in context causes it to be removed", async () => {
|
||||
mockKubeConfig.contexts.push({context: {cluster: "cluster-2", user: "cluster-2"}, name: ""});
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "cluster-2", user: "cluster-2" }, name: "" });
|
||||
expect(mockKubeConfig.contexts.length).toBe(2);
|
||||
const { config } = loadConfigFromString(JSON.stringify(mockKubeConfig));
|
||||
|
||||
@ -218,7 +218,7 @@ describe("kube helpers", () => {
|
||||
});
|
||||
|
||||
it("empty cluster in context causes it to be removed", async () => {
|
||||
mockKubeConfig.contexts.push({context: {cluster: "", user: "cluster-2"}, name: "cluster-2"});
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "", user: "cluster-2" }, name: "cluster-2" });
|
||||
expect(mockKubeConfig.contexts.length).toBe(2);
|
||||
const { config } = loadConfigFromString(JSON.stringify(mockKubeConfig));
|
||||
|
||||
@ -227,7 +227,7 @@ describe("kube helpers", () => {
|
||||
});
|
||||
|
||||
it("empty user in context causes it to be removed", async () => {
|
||||
mockKubeConfig.contexts.push({context: {cluster: "cluster-2", user: ""}, name: "cluster-2"});
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "cluster-2", user: "" }, name: "cluster-2" });
|
||||
expect(mockKubeConfig.contexts.length).toBe(2);
|
||||
const { config } = loadConfigFromString(JSON.stringify(mockKubeConfig));
|
||||
|
||||
@ -236,8 +236,8 @@ describe("kube helpers", () => {
|
||||
});
|
||||
|
||||
it("invalid context in between valid contexts is removed", async () => {
|
||||
mockKubeConfig.contexts.push({context: {cluster: "cluster-2", user: ""}, name: "cluster-2"});
|
||||
mockKubeConfig.contexts.push({context: {cluster: "cluster-3", user: "cluster-3"}, name: "cluster-3"});
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "cluster-2", user: "" }, name: "cluster-2" });
|
||||
mockKubeConfig.contexts.push({ context: { cluster: "cluster-3", user: "cluster-3" }, name: "cluster-3" });
|
||||
expect(mockKubeConfig.contexts.length).toBe(3);
|
||||
const { config } = loadConfigFromString(JSON.stringify(mockKubeConfig));
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ let searchStore: SearchStore = null;
|
||||
const logs = [
|
||||
"1:M 30 Oct 2020 16:17:41.553 # Connection with replica 172.17.0.12:6379 lost",
|
||||
"1:M 30 Oct 2020 16:17:41.623 * Replica 172.17.0.12:6379 asks for synchronization",
|
||||
"1:M 30 Oct 2020 16:17:41.623 * Starting Partial resynchronization request from 172.17.0.12:6379 accepted. Sending 0 bytes of backlog starting from offset 14407."
|
||||
"1:M 30 Oct 2020 16:17:41.623 * Starting Partial resynchronization request from 172.17.0.12:6379 accepted. Sending 0 bytes of backlog starting from offset 14407.",
|
||||
];
|
||||
|
||||
describe("search store tests", () => {
|
||||
|
||||
113
src/common/__tests__/system-ca.test.ts
Normal file
113
src/common/__tests__/system-ca.test.ts
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OpenLens Authors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import https from "https";
|
||||
import os from "os";
|
||||
import { getMacRootCA, getWinRootCA, injectCAs, DSTRootCAX3 } from "../system-ca";
|
||||
import { dependencies, devDependencies } from "../../../package.json";
|
||||
|
||||
const deps = { ...dependencies, ...devDependencies };
|
||||
|
||||
// Skip the test if mac-ca is not installed, or os is not darwin
|
||||
(deps["mac-ca"] && os.platform().includes("darwin") ? describe: describe.skip)("inject CA for Mac", () => {
|
||||
// for reset https.globalAgent.options.ca after testing
|
||||
let _ca: string | Buffer | (string | Buffer)[];
|
||||
|
||||
beforeEach(() => {
|
||||
_ca = https.globalAgent.options.ca;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
https.globalAgent.options.ca = _ca;
|
||||
});
|
||||
|
||||
/**
|
||||
* The test to ensure using getMacRootCA + injectCAs injects CAs in the same way as using
|
||||
* the auto injection (require('mac-ca'))
|
||||
*/
|
||||
it("should inject the same ca as mac-ca", async () => {
|
||||
const osxCAs = await getMacRootCA();
|
||||
|
||||
injectCAs(osxCAs);
|
||||
const injected = https.globalAgent.options.ca as (string | Buffer)[];
|
||||
|
||||
await import("mac-ca");
|
||||
const injectedByMacCA = https.globalAgent.options.ca as (string | Buffer)[];
|
||||
|
||||
expect(new Set(injected)).toEqual(new Set(injectedByMacCA));
|
||||
});
|
||||
|
||||
it("shouldn't included the expired DST Root CA X3 on Mac", async () => {
|
||||
const osxCAs = await getMacRootCA();
|
||||
|
||||
injectCAs(osxCAs);
|
||||
const injected = https.globalAgent.options.ca;
|
||||
|
||||
expect(injected.includes(DSTRootCAX3)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
// Skip the test if win-ca is not installed, or os is not win32
|
||||
(deps["win-ca"] && os.platform().includes("win32") ? describe: describe.skip)("inject CA for Windows", () => {
|
||||
// for reset https.globalAgent.options.ca after testing
|
||||
let _ca: string | Buffer | (string | Buffer)[];
|
||||
|
||||
beforeEach(() => {
|
||||
_ca = https.globalAgent.options.ca;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
https.globalAgent.options.ca = _ca;
|
||||
});
|
||||
|
||||
/**
|
||||
* The test to ensure using win-ca/api injects CAs in the same way as using
|
||||
* the auto injection (require('win-ca').inject('+'))
|
||||
*/
|
||||
it("should inject the same ca as winca.inject('+')", async () => {
|
||||
const winCAs = await getWinRootCA();
|
||||
|
||||
const wincaAPI = await import("win-ca/api");
|
||||
|
||||
wincaAPI.inject("+", winCAs);
|
||||
const injected = https.globalAgent.options.ca as (string | Buffer)[];
|
||||
|
||||
const winca = await import("win-ca");
|
||||
|
||||
winca.inject("+"); // see: https://github.com/ukoloff/win-ca#caveats
|
||||
const injectedByWinCA = https.globalAgent.options.ca as (string | Buffer)[];
|
||||
|
||||
expect(new Set(injected)).toEqual(new Set(injectedByWinCA));
|
||||
});
|
||||
|
||||
it("shouldn't included the expired DST Root CA X3 on Windows", async () => {
|
||||
const winCAs = await getWinRootCA();
|
||||
|
||||
const wincaAPI = await import("win-ca/api");
|
||||
|
||||
wincaAPI.inject("true", winCAs);
|
||||
const injected = https.globalAgent.options.ca as (string | Buffer)[];
|
||||
|
||||
expect(injected.includes(DSTRootCAX3)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ AppPaths.init();
|
||||
describe("user store tests", () => {
|
||||
describe("for an empty config", () => {
|
||||
beforeEach(() => {
|
||||
mockFs({ tmp: { "config.json": "{}", "kube_config": "{}" } });
|
||||
mockFs({ tmp: { "config.json": "{}", "kube_config": "{}" }});
|
||||
|
||||
(UserStore.createInstance() as any).refreshNewContexts = jest.fn(() => Promise.resolve());
|
||||
});
|
||||
@ -106,7 +106,7 @@ describe("user store tests", () => {
|
||||
"config.json": JSON.stringify({
|
||||
user: { username: "foobar" },
|
||||
preferences: { colorTheme: "light" },
|
||||
lastSeenAppVersion: "1.2.3"
|
||||
lastSeenAppVersion: "1.2.3",
|
||||
}),
|
||||
"lens-cluster-store.json": JSON.stringify({
|
||||
clusters: [
|
||||
@ -118,15 +118,15 @@ describe("user store tests", () => {
|
||||
id: "barfoo",
|
||||
kubeConfigPath: "some/other/path",
|
||||
},
|
||||
]
|
||||
],
|
||||
} as ClusterStoreModel),
|
||||
"extension_data": {},
|
||||
},
|
||||
"some": {
|
||||
"other": {
|
||||
"path": "is file",
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
UserStore.createInstance();
|
||||
|
||||
@ -26,13 +26,13 @@ describe("kubernetesClusterCategory", () => {
|
||||
icon: "Icon",
|
||||
title: "Title",
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
onClick: () => {}
|
||||
onClick: () => {},
|
||||
};
|
||||
const item2 = {
|
||||
icon: "Icon 2",
|
||||
title: "Title 2",
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
onClick: () => {}
|
||||
onClick: () => {},
|
||||
};
|
||||
|
||||
it("returns all items if no filter set", () => {
|
||||
|
||||
@ -57,19 +57,19 @@ export class GeneralCategory extends CatalogCategory {
|
||||
public readonly kind = "CatalogCategory";
|
||||
public metadata = {
|
||||
name: "General",
|
||||
icon: "settings"
|
||||
icon: "settings",
|
||||
};
|
||||
public spec = {
|
||||
group: "entity.k8slens.dev",
|
||||
versions: [
|
||||
{
|
||||
name: "v1alpha1",
|
||||
entityClass: GeneralEntity
|
||||
}
|
||||
entityClass: GeneralEntity,
|
||||
},
|
||||
],
|
||||
names: {
|
||||
kind: "General"
|
||||
}
|
||||
kind: "General",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ export enum LensKubernetesClusterStatus {
|
||||
DELETING = "deleting",
|
||||
CONNECTING = "connecting",
|
||||
CONNECTED = "connected",
|
||||
DISCONNECTED = "disconnected"
|
||||
DISCONNECTED = "disconnected",
|
||||
}
|
||||
|
||||
export interface KubernetesClusterMetadata extends CatalogEntityMetadata {
|
||||
@ -128,14 +128,14 @@ export class KubernetesCluster extends CatalogEntity<KubernetesClusterMetadata,
|
||||
context.menuItems.push({
|
||||
title: "Disconnect",
|
||||
icon: "link_off",
|
||||
onClick: () => requestMain(clusterDisconnectHandler, this.metadata.uid)
|
||||
onClick: () => requestMain(clusterDisconnectHandler, this.metadata.uid),
|
||||
});
|
||||
break;
|
||||
case LensKubernetesClusterStatus.DISCONNECTED:
|
||||
context.menuItems.push({
|
||||
title: "Connect",
|
||||
icon: "link",
|
||||
onClick: () => context.navigate(`/cluster/${this.metadata.uid}`)
|
||||
onClick: () => context.navigate(`/cluster/${this.metadata.uid}`),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -158,12 +158,12 @@ class KubernetesClusterCategory extends CatalogCategory {
|
||||
versions: [
|
||||
{
|
||||
name: "v1alpha1",
|
||||
entityClass: KubernetesCluster
|
||||
}
|
||||
entityClass: KubernetesCluster,
|
||||
},
|
||||
],
|
||||
names: {
|
||||
kind: "KubernetesCluster"
|
||||
}
|
||||
kind: "KubernetesCluster",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -56,8 +56,8 @@ export class WebLink extends CatalogEntity<CatalogEntityMetadata, WebLinkStatus,
|
||||
icon: "delete",
|
||||
onClick: async () => WeblinkStore.getInstance().removeById(this.metadata.uid),
|
||||
confirm: {
|
||||
message: `Remove Web Link "${this.metadata.name}" from ${productName}?`
|
||||
}
|
||||
message: `Remove Web Link "${this.metadata.name}" from ${productName}?`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -72,19 +72,19 @@ export class WebLinkCategory extends CatalogCategory {
|
||||
public readonly kind = "CatalogCategory";
|
||||
public metadata = {
|
||||
name: "Web Links",
|
||||
icon: "public"
|
||||
icon: "public",
|
||||
};
|
||||
public spec = {
|
||||
group: "entity.k8slens.dev",
|
||||
versions: [
|
||||
{
|
||||
name: "v1alpha1",
|
||||
entityClass: WebLink
|
||||
}
|
||||
entityClass: WebLink,
|
||||
},
|
||||
],
|
||||
names: {
|
||||
kind: "WebLink"
|
||||
}
|
||||
kind: "WebLink",
|
||||
},
|
||||
};
|
||||
public static onAdd?: () => void;
|
||||
|
||||
@ -97,7 +97,7 @@ export class WebLinkCategory extends CatalogCategory {
|
||||
title: "Add web link",
|
||||
onClick: () => {
|
||||
WebLinkCategory.onAdd();
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ export class CatalogCategoryRegistry {
|
||||
this.filters,
|
||||
iter.filter,
|
||||
this.items.values(),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ export abstract class CatalogCategory extends (EventEmitter as new () => TypedEm
|
||||
this.filters,
|
||||
iter.filter,
|
||||
menuItems.values(),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ export interface ClusterPrometheusPreferences {
|
||||
export enum ClusterStatus {
|
||||
AccessGranted = 2,
|
||||
AccessDenied = 1,
|
||||
Offline = 0
|
||||
Offline = 0,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,7 +131,7 @@ export enum ClusterMetadataKey {
|
||||
DISTRIBUTION = "distribution",
|
||||
NODES_COUNT = "nodes",
|
||||
LAST_SEEN = "lastSeen",
|
||||
PROMETHEUS = "prometheus"
|
||||
PROMETHEUS = "prometheus",
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -23,27 +23,25 @@ import esbuild from "esbuild";
|
||||
|
||||
/**
|
||||
* A function returning webpack ts/tsx loader
|
||||
*
|
||||
*
|
||||
* depends on env LENS_DEV_USE_ESBUILD_LOADER to use esbuild-loader (faster) or good-old ts-loader
|
||||
*
|
||||
* @param testRegExp - the regex for webpack to conditional find the files
|
||||
*
|
||||
* @param testRegExp - the regex for webpack to conditional find the files
|
||||
* @returns ts/tsx webpack loader configuration object
|
||||
*/
|
||||
const getTSLoader = (
|
||||
testRegExp: RegExp, transpileOnly = true
|
||||
testRegExp: RegExp, transpileOnly = true,
|
||||
) => {
|
||||
const useEsbuildLoader = process.env.LENS_DEV_USE_ESBUILD_LOADER === "true";
|
||||
if (process.env.LENS_DEV_USE_ESBUILD_LOADER === "true") {
|
||||
console.info(`\n🚀 using esbuild-loader for ts(x)`);
|
||||
|
||||
useEsbuildLoader && console.info(`\n🚀 using esbuild-loader for ts(x)`);
|
||||
|
||||
if (useEsbuildLoader) {
|
||||
return {
|
||||
test: testRegExp,
|
||||
loader: "esbuild-loader",
|
||||
options: {
|
||||
loader: "tsx",
|
||||
target: "es2015",
|
||||
implementation: esbuild
|
||||
implementation: esbuild,
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -55,8 +53,8 @@ const getTSLoader = (
|
||||
loader: "ts-loader",
|
||||
options: {
|
||||
transpileOnly,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -73,8 +73,8 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
protected fromStore(data: Partial<HotbarStoreModel> = {}) {
|
||||
if (!data.hotbars || !data.hotbars.length) {
|
||||
const hotbar = getEmptyHotbar("Default");
|
||||
const { metadata: { uid, name, source } } = catalogEntity;
|
||||
const initialItem = { entity: { uid, name, source } };
|
||||
const { metadata: { uid, name, source }} = catalogEntity;
|
||||
const initialItem = { entity: { uid, name, source }};
|
||||
|
||||
hotbar.items[0] = initialItem;
|
||||
|
||||
@ -99,7 +99,7 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
toJSON(): HotbarStoreModel {
|
||||
const model: HotbarStoreModel = {
|
||||
hotbars: this.hotbars,
|
||||
activeHotbarId: this.activeHotbarId
|
||||
activeHotbarId: this.activeHotbarId,
|
||||
};
|
||||
|
||||
return toJS(model);
|
||||
@ -187,7 +187,7 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
} else if (0 <= cellIndex && cellIndex < hotbar.items.length) {
|
||||
hotbar.items[cellIndex] = newItem;
|
||||
} else {
|
||||
logger.error(`[HOTBAR-STORE]: cannot pin entity to hotbar outside of index range`, { entityId: uid, hotbarId: hotbar.id, cellIndex, });
|
||||
logger.error(`[HOTBAR-STORE]: cannot pin entity to hotbar outside of index range`, { entityId: uid, hotbarId: hotbar.id, cellIndex });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -49,20 +49,20 @@ function getSubFrames(): ClusterFrameInfo[] {
|
||||
}
|
||||
|
||||
export function broadcastMessage(channel: string, ...args: any[]) {
|
||||
const views: undefined | ReturnType<typeof webContents.getAllWebContents> | ReturnType<typeof remote.webContents.getAllWebContents> = (webContents || electronRemote?.webContents)?.getAllWebContents();
|
||||
|
||||
if (!views || !Array.isArray(views) || views.length === 0) return;
|
||||
args = args.map(sanitizePayload);
|
||||
|
||||
ipcRenderer?.send(channel, ...args);
|
||||
ipcMain?.emit(channel, ...args);
|
||||
|
||||
const subFramesP = ipcRenderer
|
||||
? requestMain(subFramesChannel)
|
||||
: Promise.resolve(getSubFrames());
|
||||
|
||||
subFramesP
|
||||
.then(subFrames => {
|
||||
const views: undefined | ReturnType<typeof webContents.getAllWebContents> | ReturnType<typeof remote.webContents.getAllWebContents> = (webContents || electronRemote?.webContents)?.getAllWebContents();
|
||||
|
||||
if (!views || !Array.isArray(views) || views.length === 0) return;
|
||||
args = args.map(sanitizePayload);
|
||||
|
||||
ipcRenderer?.send(channel, ...args);
|
||||
ipcMain?.emit(channel, ...args);
|
||||
|
||||
for (const view of views) {
|
||||
let viewType = "unknown";
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ export type Rest<T> = T extends [any, ...infer R] ? R : [];
|
||||
*/
|
||||
export function onceCorrect<
|
||||
IPC extends EventEmitter,
|
||||
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any
|
||||
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any,
|
||||
>({
|
||||
source,
|
||||
channel,
|
||||
@ -72,7 +72,7 @@ export function onceCorrect<
|
||||
*/
|
||||
export function onCorrect<
|
||||
IPC extends EventEmitter,
|
||||
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any
|
||||
Listener extends (event: ListenerEvent<IPC>, ...args: any[]) => any,
|
||||
>({
|
||||
source,
|
||||
channel,
|
||||
|
||||
@ -119,7 +119,7 @@ describe("Crds", () => {
|
||||
},
|
||||
spec: {
|
||||
version: "abc",
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(crd.getVersion()).toBe("abc");
|
||||
|
||||
@ -41,19 +41,19 @@ describe("DeploymentApi", () => {
|
||||
it("requests Kubernetes API with PATCH verb and correct amount of replicas", () => {
|
||||
const patchSpy = jest.spyOn(requestMock, "patch");
|
||||
|
||||
sub.scale({ namespace: "default", name: "deployment-1"}, 5);
|
||||
sub.scale({ namespace: "default", name: "deployment-1" }, 5);
|
||||
|
||||
expect(patchSpy).toHaveBeenCalledWith("/apis/apps/v1/namespaces/default/deployments/deployment-1/scale", {
|
||||
data: {
|
||||
spec: {
|
||||
replicas: 5
|
||||
}
|
||||
}
|
||||
replicas: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/merge-patch+json"
|
||||
}
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -282,7 +282,7 @@ describe("HelmChart tests", () => {
|
||||
|
||||
expect(warnFn).toHaveBeenCalledWith("HelmChart data has unexpected fields", {
|
||||
original: anyObject(),
|
||||
unknownFields: ["asdjhajksdhadjks"]
|
||||
unknownFields: ["asdjhajksdhadjks"],
|
||||
});
|
||||
console.warn = warn;
|
||||
});
|
||||
|
||||
@ -26,7 +26,7 @@ jest.mock("../api-manager", () => ({
|
||||
return {
|
||||
registerStore: jest.fn(),
|
||||
};
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
import { IKubeApiParsed, parseKubeApi } from "../kube-api-parse";
|
||||
@ -45,7 +45,7 @@ const tests: KubeApiParseTestData[] = [
|
||||
apiVersionWithGroup: "apiextensions.k8s.io/v1beta1",
|
||||
namespace: undefined,
|
||||
resource: "customresourcedefinitions",
|
||||
name: "prometheuses.monitoring.coreos.com"
|
||||
name: "prometheuses.monitoring.coreos.com",
|
||||
}],
|
||||
["/api/v1/namespaces/kube-system/pods/coredns-6955765f44-v8p27", {
|
||||
apiBase: "/api/v1/pods",
|
||||
@ -55,7 +55,7 @@ const tests: KubeApiParseTestData[] = [
|
||||
apiVersionWithGroup: "v1",
|
||||
namespace: "kube-system",
|
||||
resource: "pods",
|
||||
name: "coredns-6955765f44-v8p27"
|
||||
name: "coredns-6955765f44-v8p27",
|
||||
}],
|
||||
["/apis/stable.example.com/foo1/crontabs", {
|
||||
apiBase: "/apis/stable.example.com/foo1/crontabs",
|
||||
@ -132,7 +132,7 @@ const tests: KubeApiParseTestData[] = [
|
||||
const throwtests = [
|
||||
undefined,
|
||||
"",
|
||||
"ajklsmh"
|
||||
"ajklsmh",
|
||||
];
|
||||
|
||||
describe("parseApi unit tests", () => {
|
||||
|
||||
@ -28,11 +28,11 @@ describe("forRemoteCluster", () => {
|
||||
it("builds api client", async (done) => {
|
||||
const api = forRemoteCluster({
|
||||
cluster: {
|
||||
server: "https://127.0.0.1:6443"
|
||||
server: "https://127.0.0.1:6443",
|
||||
},
|
||||
user: {
|
||||
token: "daa"
|
||||
}
|
||||
token: "daa",
|
||||
},
|
||||
}, Pod);
|
||||
|
||||
(fetch as any).mockResponse(async (request: any) => {
|
||||
@ -41,7 +41,7 @@ describe("forRemoteCluster", () => {
|
||||
done();
|
||||
|
||||
return {
|
||||
body: ""
|
||||
body: "",
|
||||
};
|
||||
});
|
||||
|
||||
@ -55,7 +55,7 @@ describe("KubeApi", () => {
|
||||
beforeEach(() => {
|
||||
request = new KubeJsonApi({
|
||||
serverAddress: `http://127.0.0.1:9999`,
|
||||
apiBase: "/api-kube"
|
||||
apiBase: "/api-kube",
|
||||
});
|
||||
});
|
||||
|
||||
@ -65,24 +65,24 @@ describe("KubeApi", () => {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any[]
|
||||
})
|
||||
name: "ingresses",
|
||||
}] as any[],
|
||||
}),
|
||||
};
|
||||
} else if (request.url === "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1") {
|
||||
// Even if the old API contains ingresses, KubeApi should prefer the apiBase url
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any[]
|
||||
})
|
||||
name: "ingresses",
|
||||
}] as any[],
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any[]
|
||||
})
|
||||
resources: [] as any[],
|
||||
}),
|
||||
};
|
||||
}
|
||||
});
|
||||
@ -107,22 +107,22 @@ describe("KubeApi", () => {
|
||||
if (request.url === "http://127.0.0.1:9999/api-kube/apis/networking.k8s.io/v1") {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any[]
|
||||
})
|
||||
resources: [] as any[],
|
||||
}),
|
||||
};
|
||||
} else if (request.url === "http://127.0.0.1:9999/api-kube/apis/extensions/v1beta1") {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [{
|
||||
name: "ingresses"
|
||||
}] as any[]
|
||||
})
|
||||
name: "ingresses",
|
||||
}] as any[],
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
body: JSON.stringify({
|
||||
resources: [] as any[]
|
||||
})
|
||||
resources: [] as any[],
|
||||
}),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@ -45,12 +45,12 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { apiVersion: "", metadata: {uid: "", name: "", resourceVersion: "", selfLink: ""} }],
|
||||
["apiVersion", { kind: "", metadata: {uid: "", name: "", resourceVersion: "", selfLink: ""} }],
|
||||
["kind", { apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["apiVersion", { kind: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata", { kind: "", apiVersion: "" }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { name: "", resourceVersion: "", selfLink: ""} }],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", resourceVersion: "", selfLink: "" } }],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", selfLink: "" } }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", selfLink: "" }}],
|
||||
];
|
||||
|
||||
it.each(tests)("should reject with missing: %s", (missingField, input) => {
|
||||
@ -61,23 +61,23 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { kind: 1, apiVersion: "", metadata: {} }],
|
||||
["apiVersion", { apiVersion: 1, kind: "", metadata: {} }],
|
||||
["kind", { kind: 1, apiVersion: "", metadata: {}}],
|
||||
["apiVersion", { apiVersion: 1, kind: "", metadata: {}}],
|
||||
["metadata", { kind: "", apiVersion: "", metadata: "" }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { uid: 1 } }],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", name: 1 } }],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: 1 } }],
|
||||
["metadata.selfLink", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: 1 } }],
|
||||
["metadata.namespace", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", namespace: 1 } }],
|
||||
["metadata.creationTimestamp", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", creationTimestamp: 1 } }],
|
||||
["metadata.continue", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", continue: 1 } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: 1 } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: [1] } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: {} } }],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: 1 } }],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: { food: 1 } } }],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: 1 } }],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: 1 } } }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { uid: 1 }}],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", name: 1 }}],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: 1 }}],
|
||||
["metadata.selfLink", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: 1 }}],
|
||||
["metadata.namespace", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", namespace: 1 }}],
|
||||
["metadata.creationTimestamp", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", creationTimestamp: 1 }}],
|
||||
["metadata.continue", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", continue: 1 }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: 1 }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: [1] }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: {}}}],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: 1 }}],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: { food: 1 }}}],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: 1 }}],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: 1 }}}],
|
||||
];
|
||||
|
||||
it.each(tests)("should reject with wrong type for field: %s", (missingField, input) => {
|
||||
@ -86,7 +86,7 @@ describe("KubeObject", () => {
|
||||
}
|
||||
|
||||
it("should accept valid KubeJsonApiData (ignoring other fields)", () => {
|
||||
const valid = { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: "" } } };
|
||||
const valid = { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: "" }}};
|
||||
|
||||
expect(KubeObject.isJsonApiData(valid)).toBe(true);
|
||||
});
|
||||
@ -118,8 +118,8 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" } }],
|
||||
["apiVersion", { kind: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" } }],
|
||||
["kind", { apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["apiVersion", { kind: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata", { kind: "", apiVersion: "" }],
|
||||
];
|
||||
|
||||
@ -131,23 +131,23 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { kind: 1, apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" } }],
|
||||
["apiVersion", { apiVersion: 1, kind: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" } }],
|
||||
["kind", { kind: 1, apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["apiVersion", { apiVersion: 1, kind: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata", { kind: "", apiVersion: "", metadata: "" }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { uid: 1, name: "", resourceVersion: "", selfLink: "" } }],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", name: 1, resourceVersion: "", selfLink: "" } }],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: 1, selfLink: "" } }],
|
||||
["metadata.selfLink", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: 1 } }],
|
||||
["metadata.namespace", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", namespace: 1 } }],
|
||||
["metadata.creationTimestamp", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", creationTimestamp: 1 } }],
|
||||
["metadata.continue", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", continue: 1 } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: 1 } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: [1] } }],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: {} } }],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: 1 } }],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: { food: 1 } } }],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: 1 } }],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: 1 } } }],
|
||||
["metadata.uid", { kind: "", apiVersion: "", metadata: { uid: 1, name: "", resourceVersion: "", selfLink: "" }}],
|
||||
["metadata.name", { kind: "", apiVersion: "", metadata: { uid: "", name: 1, resourceVersion: "", selfLink: "" }}],
|
||||
["metadata.resourceVersion", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: 1, selfLink: "" }}],
|
||||
["metadata.selfLink", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: 1 }}],
|
||||
["metadata.namespace", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", namespace: 1 }}],
|
||||
["metadata.creationTimestamp", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", creationTimestamp: 1 }}],
|
||||
["metadata.continue", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", continue: 1 }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: 1 }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: [1] }}],
|
||||
["metadata.finalizers", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", finalizers: {}}}],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: 1 }}],
|
||||
["metadata.labels", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", labels: { food: 1 }}}],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: 1 }}],
|
||||
["metadata.annotations", { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: 1 }}}],
|
||||
];
|
||||
|
||||
it.each(tests)("should reject with wrong type for field: %s", (missingField, input) => {
|
||||
@ -156,7 +156,7 @@ describe("KubeObject", () => {
|
||||
}
|
||||
|
||||
it("should accept valid Partial<KubeJsonApiData> (ignoring other fields)", () => {
|
||||
const valid = { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: "" } } };
|
||||
const valid = { kind: "", apiVersion: "", metadata: { uid: "", name: "", resourceVersion: "", selfLink: "", annotations: { food: "" }}};
|
||||
|
||||
expect(KubeObject.isPartialJsonApiData(valid)).toBe(true);
|
||||
});
|
||||
@ -197,8 +197,8 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { apiVersion: "", items: [], metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["apiVersion", { kind: "", items: [], metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["kind", { apiVersion: "", items: [], metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["apiVersion", { kind: "", items: [], metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["metadata", { kind: "", items: [], apiVersion: "" }],
|
||||
];
|
||||
|
||||
@ -210,15 +210,15 @@ describe("KubeObject", () => {
|
||||
{
|
||||
type TestCase = [string, any];
|
||||
const tests: TestCase[] = [
|
||||
["kind", { kind: 1, items: [], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["apiVersion", { kind: "", items: [], apiVersion: 1, metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["kind", { kind: 1, items: [], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["apiVersion", { kind: "", items: [], apiVersion: 1, metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["metadata", { kind: "", items: [], apiVersion: "", metadata: 1 }],
|
||||
["metadata.resourceVersion", { kind: "", items: [], apiVersion: "", metadata: { resourceVersion: 1, selfLink: "" } }],
|
||||
["metadata.selfLink", { kind: "", items: [], apiVersion: "", metadata: { resourceVersion: "", selfLink: 1 } }],
|
||||
["items", { kind: "", items: 1, apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["items", { kind: "", items: "", apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["items", { kind: "", items: {}, apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["items[0]", { kind: "", items: [""], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } }],
|
||||
["metadata.resourceVersion", { kind: "", items: [], apiVersion: "", metadata: { resourceVersion: 1, selfLink: "" }}],
|
||||
["metadata.selfLink", { kind: "", items: [], apiVersion: "", metadata: { resourceVersion: "", selfLink: 1 }}],
|
||||
["items", { kind: "", items: 1, apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["items", { kind: "", items: "", apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["items", { kind: "", items: {}, apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
["items[0]", { kind: "", items: [""], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }}],
|
||||
];
|
||||
|
||||
it.each(tests)("should reject with wrong type for field: %s", (missingField, input) => {
|
||||
@ -227,7 +227,7 @@ describe("KubeObject", () => {
|
||||
}
|
||||
|
||||
it("should accept valid KubeJsonApiDataList (ignoring other fields)", () => {
|
||||
const valid = { kind: "", items: [false], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" } };
|
||||
const valid = { kind: "", items: [false], apiVersion: "", metadata: { resourceVersion: "", selfLink: "" }};
|
||||
|
||||
expect(KubeObject.isJsonApiDataList(valid, isBoolean)).toBe(true);
|
||||
});
|
||||
|
||||
@ -45,8 +45,8 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po
|
||||
uid: "1",
|
||||
name: "test",
|
||||
resourceVersion: "v1",
|
||||
selfLink: "http"
|
||||
}
|
||||
selfLink: "http",
|
||||
},
|
||||
});
|
||||
|
||||
pod.spec = {
|
||||
@ -82,9 +82,9 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po
|
||||
restartCount: i,
|
||||
state: {
|
||||
running: {
|
||||
startedAt: "before"
|
||||
startedAt: "before",
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -107,9 +107,9 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po
|
||||
startedAt: "before",
|
||||
exitCode: i+1,
|
||||
finishedAt: "later",
|
||||
reason: `reason_${i}`
|
||||
}
|
||||
}
|
||||
reason: `reason_${i}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -129,9 +129,9 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po
|
||||
restartCount: i,
|
||||
state: {
|
||||
running: {
|
||||
startedAt: "before"
|
||||
}
|
||||
}
|
||||
startedAt: "before",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -154,9 +154,9 @@ function getDummyPod(opts: GetDummyPodOptions = getDummyPodDefaultOptions()): Po
|
||||
startedAt: "before",
|
||||
exitCode: i+1,
|
||||
finishedAt: "later",
|
||||
reason: `reason_${i}`
|
||||
}
|
||||
}
|
||||
reason: `reason_${i}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ describe("Pods", () => {
|
||||
return {
|
||||
image: "dummy",
|
||||
imagePullPolicy: "dummy",
|
||||
name
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ describe("Pods", () => {
|
||||
const pod = getDummyPod();
|
||||
|
||||
pod.spec.nodeSelector = {
|
||||
"kubernetes.io/os": "foobar"
|
||||
"kubernetes.io/os": "foobar",
|
||||
};
|
||||
|
||||
expect(pod.getSelectedNodeOs()).toStrictEqual("foobar");
|
||||
@ -241,7 +241,7 @@ describe("Pods", () => {
|
||||
const pod = getDummyPod();
|
||||
|
||||
pod.spec.nodeSelector = {
|
||||
"beta.kubernetes.io/os": "foobar1"
|
||||
"beta.kubernetes.io/os": "foobar1",
|
||||
};
|
||||
|
||||
expect(pod.getSelectedNodeOs()).toStrictEqual("foobar1");
|
||||
@ -252,7 +252,7 @@ describe("Pods", () => {
|
||||
|
||||
pod.spec.nodeSelector = {
|
||||
"kubernetes.io/os": "foobar2",
|
||||
"beta.kubernetes.io/os": "foobar3"
|
||||
"beta.kubernetes.io/os": "foobar3",
|
||||
};
|
||||
|
||||
expect(pod.getSelectedNodeOs()).toStrictEqual("foobar2");
|
||||
@ -273,7 +273,7 @@ describe("Pods", () => {
|
||||
type: "Ready",
|
||||
status: "foobar",
|
||||
lastProbeTime: 1,
|
||||
lastTransitionTime: "longer ago"
|
||||
lastTransitionTime: "longer ago",
|
||||
});
|
||||
|
||||
expect(pod.hasIssues()).toStrictEqual(true);
|
||||
@ -286,7 +286,7 @@ describe("Pods", () => {
|
||||
type: "dummy",
|
||||
status: "foobar",
|
||||
lastProbeTime: 1,
|
||||
lastTransitionTime: "longer ago"
|
||||
lastTransitionTime: "longer ago",
|
||||
});
|
||||
|
||||
expect(pod.hasIssues()).toStrictEqual(false);
|
||||
@ -298,8 +298,8 @@ describe("Pods", () => {
|
||||
pod.status.containerStatuses[0].state = {
|
||||
waiting: {
|
||||
reason: "CrashLookBackOff",
|
||||
message: "too much foobar"
|
||||
}
|
||||
message: "too much foobar",
|
||||
},
|
||||
};
|
||||
|
||||
expect(pod.hasIssues()).toStrictEqual(true);
|
||||
|
||||
@ -41,19 +41,19 @@ describe("StatefulSetApi", () => {
|
||||
it("requests Kubernetes API with PATCH verb and correct amount of replicas", () => {
|
||||
const patchSpy = jest.spyOn(requestMock, "patch");
|
||||
|
||||
sub.scale({ namespace: "default", name: "statefulset-1"}, 5);
|
||||
sub.scale({ namespace: "default", name: "statefulset-1" }, 5);
|
||||
|
||||
expect(patchSpy).toHaveBeenCalledWith("/apis/apps/v1/namespaces/default/statefulsets/statefulset-1/scale", {
|
||||
data: {
|
||||
spec: {
|
||||
replicas: 5
|
||||
}
|
||||
}
|
||||
replicas: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/merge-patch+json"
|
||||
}
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -98,7 +98,7 @@ export class ApiManager {
|
||||
lookupApiLink(ref: IKubeObjectRef, parentObject: KubeObject): string {
|
||||
const {
|
||||
kind, apiVersion, name,
|
||||
namespace = parentObject.getNs()
|
||||
namespace = parentObject.getNs(),
|
||||
} = ref;
|
||||
|
||||
if (!kind) return "";
|
||||
|
||||
@ -66,5 +66,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
clusterRoleBindingApi
|
||||
clusterRoleBindingApi,
|
||||
};
|
||||
|
||||
@ -54,5 +54,5 @@ if (isClusterPageContext()) { // initialize automatically only when within a clu
|
||||
}
|
||||
|
||||
export {
|
||||
clusterRoleApi
|
||||
clusterRoleApi,
|
||||
};
|
||||
|
||||
@ -49,7 +49,7 @@ export function getMetricsByNodeNames(nodeNames: string[], params?: IMetricsReqP
|
||||
podCapacity: opts,
|
||||
podAllocatableCapacity: opts,
|
||||
fsSize: opts,
|
||||
fsUsage: opts
|
||||
fsUsage: opts,
|
||||
}, params);
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ export enum ClusterStatus {
|
||||
ACTIVE = "Active",
|
||||
CREATING = "Creating",
|
||||
REMOVING = "Removing",
|
||||
ERROR = "Error"
|
||||
ERROR = "Error",
|
||||
}
|
||||
|
||||
export interface IClusterMetrics<T = IMetrics> {
|
||||
@ -135,5 +135,5 @@ if (isClusterPageContext()) { // initialize automatically only when within a clu
|
||||
}
|
||||
|
||||
export {
|
||||
clusterApi
|
||||
clusterApi,
|
||||
};
|
||||
|
||||
@ -60,5 +60,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
configMapApi
|
||||
configMapApi,
|
||||
};
|
||||
|
||||
@ -117,7 +117,7 @@ export class CustomResourceDefinition extends KubeObject {
|
||||
params: {
|
||||
group: this.getGroup(),
|
||||
name: this.getPluralName(),
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ export class CustomResourceDefinition extends KubeObject {
|
||||
}
|
||||
} else if (this.spec.version) {
|
||||
const { additionalPrinterColumns: apc } = this.spec;
|
||||
const additionalPrinterColumns = apc?.map(({ JSONPath, ...apc}) => ({ ...apc, jsonPath: JSONPath }));
|
||||
const additionalPrinterColumns = apc?.map(({ JSONPath, ...apc }) => ({ ...apc, jsonPath: JSONPath }));
|
||||
|
||||
return {
|
||||
name: this.spec.version,
|
||||
@ -217,7 +217,7 @@ export class CustomResourceDefinition extends KubeObject {
|
||||
return {
|
||||
...condition,
|
||||
isReady: status === "True",
|
||||
tooltip: `${message || reason} (${lastTransitionTime})`
|
||||
tooltip: `${message || reason} (${lastTransitionTime})`,
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -236,5 +236,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
crdApi
|
||||
crdApi,
|
||||
};
|
||||
|
||||
@ -33,14 +33,14 @@ export class CronJobApi extends KubeApi<CronJob> {
|
||||
return this.request.patch(this.getUrl(params), {
|
||||
data: {
|
||||
spec: {
|
||||
suspend: true
|
||||
}
|
||||
}
|
||||
suspend: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/strategic-merge-patch+json"
|
||||
}
|
||||
"content-type": "application/strategic-merge-patch+json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -48,14 +48,14 @@ export class CronJobApi extends KubeApi<CronJob> {
|
||||
return this.request.patch(this.getUrl(params), {
|
||||
data: {
|
||||
spec: {
|
||||
suspend: false
|
||||
}
|
||||
}
|
||||
suspend: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/strategic-merge-patch+json"
|
||||
}
|
||||
"content-type": "application/strategic-merge-patch+json",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -153,5 +153,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
cronJobApi
|
||||
cronJobApi,
|
||||
};
|
||||
|
||||
@ -129,5 +129,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
daemonSetApi
|
||||
daemonSetApi,
|
||||
};
|
||||
|
||||
@ -44,14 +44,14 @@ export class DeploymentApi extends KubeApi<Deployment> {
|
||||
return this.request.patch(this.getScaleApiUrl(params), {
|
||||
data: {
|
||||
spec: {
|
||||
replicas
|
||||
}
|
||||
}
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/merge-patch+json"
|
||||
}
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -61,16 +61,16 @@ export class DeploymentApi extends KubeApi<Deployment> {
|
||||
spec: {
|
||||
template: {
|
||||
metadata: {
|
||||
annotations: {"kubectl.kubernetes.io/restartedAt" : moment.utc().format()}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
annotations: { "kubectl.kubernetes.io/restartedAt" : moment.utc().format() },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/strategic-merge-patch+json"
|
||||
}
|
||||
"content-type": "application/strategic-merge-patch+json",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ export class Deployment extends WorkloadKubeObject {
|
||||
|
||||
declare spec: {
|
||||
replicas: number;
|
||||
selector: { matchLabels: { [app: string]: string } };
|
||||
selector: { matchLabels: { [app: string]: string }};
|
||||
template: {
|
||||
metadata: {
|
||||
creationTimestamp?: string;
|
||||
@ -246,5 +246,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
deploymentApi
|
||||
deploymentApi,
|
||||
};
|
||||
|
||||
@ -83,7 +83,7 @@ export class EndpointAddress implements IEndpointAddress {
|
||||
|
||||
getTargetRef(): ITargetRef {
|
||||
if (this.targetRef) {
|
||||
return Object.assign(this.targetRef, {apiVersion: "v1"});
|
||||
return Object.assign(this.targetRef, { apiVersion: "v1" });
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -159,5 +159,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
endpointApi
|
||||
endpointApi,
|
||||
};
|
||||
|
||||
@ -87,5 +87,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
eventApi
|
||||
eventApi,
|
||||
};
|
||||
|
||||
@ -191,7 +191,7 @@ const helmChartValidator = Joi.object<RawHelmChart>({
|
||||
.items(Joi.string())
|
||||
.options({
|
||||
stripUnknown: {
|
||||
arrays: true
|
||||
arrays: true,
|
||||
},
|
||||
})
|
||||
.default(() => ([])),
|
||||
@ -200,7 +200,7 @@ const helmChartValidator = Joi.object<RawHelmChart>({
|
||||
.items(Joi.string())
|
||||
.options({
|
||||
stripUnknown: {
|
||||
arrays: true
|
||||
arrays: true,
|
||||
},
|
||||
})
|
||||
.default(() => ([])),
|
||||
@ -209,7 +209,7 @@ const helmChartValidator = Joi.object<RawHelmChart>({
|
||||
.items(Joi.string())
|
||||
.options({
|
||||
stripUnknown: {
|
||||
arrays: true
|
||||
arrays: true,
|
||||
},
|
||||
})
|
||||
.default(() => ([])),
|
||||
@ -218,7 +218,7 @@ const helmChartValidator = Joi.object<RawHelmChart>({
|
||||
.items(helmChartMaintainerValidator)
|
||||
.options({
|
||||
stripUnknown: {
|
||||
arrays: true
|
||||
arrays: true,
|
||||
},
|
||||
})
|
||||
.default(() => ([])),
|
||||
@ -227,7 +227,7 @@ const helmChartValidator = Joi.object<RawHelmChart>({
|
||||
.items(helmChartDependencyValidator)
|
||||
.options({
|
||||
stripUnknown: {
|
||||
arrays: true
|
||||
arrays: true,
|
||||
},
|
||||
})
|
||||
.default(() => ([])),
|
||||
|
||||
@ -108,7 +108,7 @@ export async function getRelease(name: string, namespace: string): Promise<IRele
|
||||
|
||||
return {
|
||||
...details,
|
||||
resources
|
||||
resources,
|
||||
};
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ export async function createRelease(payload: IReleaseCreatePayload): Promise<IRe
|
||||
chart,
|
||||
values,
|
||||
...data,
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ export async function updateRelease(name: string, namespace: string, payload: IR
|
||||
chart,
|
||||
values,
|
||||
...data,
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
|
||||
return {
|
||||
...condition,
|
||||
isReady: status === "True",
|
||||
tooltip: `${message || reason} (${lastTransitionTime})`
|
||||
tooltip: `${message || reason} (${lastTransitionTime})`,
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -143,7 +143,7 @@ export class HorizontalPodAutoscaler extends KubeObject {
|
||||
getMetricValues(metric: IHpaMetric): string {
|
||||
const metricType = metric.type.toLowerCase();
|
||||
const currentMetric = this.getCurrentMetrics().find(current =>
|
||||
metric.type == current.type && this.getMetricName(metric) == this.getMetricName(current)
|
||||
metric.type == current.type && this.getMetricName(metric) == this.getMetricName(current),
|
||||
);
|
||||
const current = currentMetric ? currentMetric[metricType] : null;
|
||||
const target = metric[metricType];
|
||||
@ -173,5 +173,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
hpaApi
|
||||
hpaApi,
|
||||
};
|
||||
|
||||
@ -30,13 +30,13 @@ export class IngressApi extends KubeApi<Ingress> {
|
||||
}
|
||||
|
||||
export function getMetricsForIngress(ingress: string, namespace: string): Promise<IIngressMetrics> {
|
||||
const opts = { category: "ingress", ingress };
|
||||
const opts = { category: "ingress", ingress, namespace };
|
||||
|
||||
return metricsApi.getMetrics({
|
||||
bytesSentSuccess: opts,
|
||||
bytesSentFailure: opts,
|
||||
requestDurationSeconds: opts,
|
||||
responseDurationSeconds: opts
|
||||
responseDurationSeconds: opts,
|
||||
}, {
|
||||
namespace,
|
||||
});
|
||||
@ -128,7 +128,7 @@ export class Ingress extends KubeObject {
|
||||
}
|
||||
|
||||
getRoutes() {
|
||||
const { spec: { tls, rules } } = this;
|
||||
const { spec: { tls, rules }} = this;
|
||||
|
||||
if (!rules) return [];
|
||||
|
||||
@ -160,12 +160,12 @@ export class Ingress extends KubeObject {
|
||||
|
||||
return {
|
||||
serviceName,
|
||||
servicePort
|
||||
servicePort,
|
||||
};
|
||||
}
|
||||
|
||||
getHosts() {
|
||||
const { spec: { rules } } = this;
|
||||
const { spec: { rules }} = this;
|
||||
|
||||
if (!rules) return [];
|
||||
|
||||
@ -174,7 +174,7 @@ export class Ingress extends KubeObject {
|
||||
|
||||
getPorts() {
|
||||
const ports: number[] = [];
|
||||
const { spec: { tls, rules, backend, defaultBackend } } = this;
|
||||
const { spec: { tls, rules, backend, defaultBackend }} = this;
|
||||
const httpPort = 80;
|
||||
const tlsPort = 443;
|
||||
// Note: not using the port name (string)
|
||||
@ -196,7 +196,7 @@ export class Ingress extends KubeObject {
|
||||
}
|
||||
|
||||
getLoadBalancers() {
|
||||
const { status: { loadBalancer = { ingress: [] } } } = this;
|
||||
const { status: { loadBalancer = { ingress: [] }}} = this;
|
||||
|
||||
return (loadBalancer.ingress ?? []).map(address => (
|
||||
address.hostname || address.ip
|
||||
@ -216,5 +216,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
ingressApi
|
||||
ingressApi,
|
||||
};
|
||||
|
||||
@ -124,7 +124,7 @@ export class Job extends WorkloadKubeObject {
|
||||
|
||||
delete() {
|
||||
const params: JsonApiParams = {
|
||||
query: { propagationPolicy: "Background" }
|
||||
query: { propagationPolicy: "Background" },
|
||||
};
|
||||
|
||||
return super.delete(params);
|
||||
@ -158,5 +158,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
jobApi
|
||||
jobApi,
|
||||
};
|
||||
|
||||
@ -90,5 +90,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
limitRangeApi
|
||||
limitRangeApi,
|
||||
};
|
||||
|
||||
@ -87,13 +87,13 @@ export const metricsApi = {
|
||||
query: {
|
||||
start, end, step,
|
||||
"kubernetes_namespace": namespace,
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
async getMetricProviders(): Promise<MetricProviderInfo[]> {
|
||||
return apiBase.get("/metrics/providers");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
|
||||
@ -103,7 +103,7 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
|
||||
resultType: "",
|
||||
result: [{
|
||||
metric: {},
|
||||
values: []
|
||||
values: [],
|
||||
} as IMetricsResult],
|
||||
},
|
||||
status: "",
|
||||
@ -144,7 +144,7 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
|
||||
// always return at least empty values array
|
||||
result.push({
|
||||
metric: {},
|
||||
values: []
|
||||
values: [],
|
||||
} as IMetricsResult);
|
||||
}
|
||||
|
||||
|
||||
@ -79,5 +79,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
namespacesApi
|
||||
namespacesApi,
|
||||
};
|
||||
|
||||
@ -106,5 +106,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
networkPolicyApi
|
||||
networkPolicyApi,
|
||||
};
|
||||
|
||||
@ -30,7 +30,7 @@ export class NodesApi extends KubeApi<Node> {
|
||||
}
|
||||
|
||||
export function getMetricsForAllNodes(): Promise<INodeMetrics> {
|
||||
const opts = { category: "nodes"};
|
||||
const opts = { category: "nodes" };
|
||||
|
||||
return metricsApi.getMetrics({
|
||||
memoryUsage: opts,
|
||||
@ -40,7 +40,7 @@ export function getMetricsForAllNodes(): Promise<INodeMetrics> {
|
||||
cpuUsage: opts,
|
||||
cpuCapacity: opts,
|
||||
fsSize: opts,
|
||||
fsUsage: opts
|
||||
fsUsage: opts,
|
||||
});
|
||||
}
|
||||
|
||||
@ -259,5 +259,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
nodesApi
|
||||
nodesApi,
|
||||
};
|
||||
|
||||
@ -35,9 +35,9 @@ export function getMetricsForPvc(pvc: PersistentVolumeClaim): Promise<IPvcMetric
|
||||
|
||||
return metricsApi.getMetrics({
|
||||
diskUsage: opts,
|
||||
diskCapacity: opts
|
||||
diskCapacity: opts,
|
||||
}, {
|
||||
namespace: opts.namespace
|
||||
namespace: opts.namespace,
|
||||
});
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ export class PersistentVolumeClaim extends KubeObject {
|
||||
return pods.filter(pod => {
|
||||
return pod.getVolumes().filter(volume =>
|
||||
volume.persistentVolumeClaim &&
|
||||
volume.persistentVolumeClaim.claimName === this.getName()
|
||||
volume.persistentVolumeClaim.claimName === this.getName(),
|
||||
).length > 0;
|
||||
});
|
||||
}
|
||||
@ -128,5 +128,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
pvcApi
|
||||
pvcApi,
|
||||
};
|
||||
|
||||
@ -111,5 +111,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
persistentVolumeApi
|
||||
persistentVolumeApi,
|
||||
};
|
||||
|
||||
@ -50,5 +50,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
podMetricsApi
|
||||
podMetricsApi,
|
||||
};
|
||||
|
||||
@ -29,7 +29,7 @@ export interface PodDisruptionBudget {
|
||||
spec: {
|
||||
minAvailable: string;
|
||||
maxUnavailable: string;
|
||||
selector: { matchLabels: { [app: string]: string } };
|
||||
selector: { matchLabels: { [app: string]: string }};
|
||||
};
|
||||
status: {
|
||||
currentHealthy: number
|
||||
@ -82,5 +82,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
pdbApi
|
||||
pdbApi,
|
||||
};
|
||||
|
||||
@ -82,7 +82,7 @@ export enum PodStatus {
|
||||
PENDING = "Pending",
|
||||
RUNNING = "Running",
|
||||
SUCCEEDED = "Succeeded",
|
||||
EVICTED = "Evicted"
|
||||
EVICTED = "Evicted",
|
||||
}
|
||||
|
||||
export interface IPodContainer extends Partial<Record<PodContainerProbe, IContainerProbe>> {
|
||||
@ -310,7 +310,7 @@ export class Pod extends WorkloadKubeObject {
|
||||
const runningContainerNames = new Set(
|
||||
this.getContainerStatuses()
|
||||
.filter(({ state }) => state.running)
|
||||
.map(({ name }) => name)
|
||||
.map(({ name }) => name),
|
||||
);
|
||||
|
||||
return this.getAllContainers()
|
||||
@ -411,7 +411,7 @@ export class Pod extends WorkloadKubeObject {
|
||||
}
|
||||
|
||||
getNodeSelectors(): string[] {
|
||||
const { nodeSelector = {} } = this.spec;
|
||||
const { nodeSelector = {}} = this.spec;
|
||||
|
||||
return Object.entries(nodeSelector).map(values => values.join(": "));
|
||||
}
|
||||
@ -466,7 +466,7 @@ export class Pod extends WorkloadKubeObject {
|
||||
timeoutSeconds = 0,
|
||||
periodSeconds = 0,
|
||||
successThreshold = 0,
|
||||
failureThreshold = 0
|
||||
failureThreshold = 0,
|
||||
} = probeData;
|
||||
|
||||
// HTTP Request
|
||||
@ -529,5 +529,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
podsApi
|
||||
podsApi,
|
||||
};
|
||||
|
||||
@ -127,5 +127,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
pspApi
|
||||
pspApi,
|
||||
};
|
||||
|
||||
@ -44,9 +44,9 @@ export class ReplicaSetApi extends KubeApi<ReplicaSet> {
|
||||
data: {
|
||||
metadata: params,
|
||||
spec: {
|
||||
replicas
|
||||
}
|
||||
}
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ export class ReplicaSet extends WorkloadKubeObject {
|
||||
|
||||
declare spec: {
|
||||
replicas?: number;
|
||||
selector: { matchLabels: { [app: string]: string } };
|
||||
selector: { matchLabels: { [app: string]: string }};
|
||||
template?: {
|
||||
metadata: {
|
||||
labels: {
|
||||
@ -133,5 +133,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
replicaSetApi
|
||||
replicaSetApi,
|
||||
};
|
||||
|
||||
@ -25,7 +25,7 @@ import { apiBase } from "../index";
|
||||
import type { Patch } from "rfc6902";
|
||||
|
||||
export const annotations = [
|
||||
"kubectl.kubernetes.io/last-applied-configuration"
|
||||
"kubectl.kubernetes.io/last-applied-configuration",
|
||||
];
|
||||
|
||||
export async function update(resource: object | string): Promise<KubeJsonApiData> {
|
||||
|
||||
@ -90,5 +90,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
resourceQuotaApi
|
||||
resourceQuotaApi,
|
||||
};
|
||||
|
||||
@ -71,5 +71,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
roleBindingApi
|
||||
roleBindingApi,
|
||||
};
|
||||
|
||||
@ -51,5 +51,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export{
|
||||
roleApi
|
||||
roleApi,
|
||||
};
|
||||
|
||||
@ -79,5 +79,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
secretsApi
|
||||
secretsApi,
|
||||
};
|
||||
|
||||
@ -27,7 +27,7 @@ export class SelfSubjectRulesReviewApi extends KubeApi<SelfSubjectRulesReview> {
|
||||
create({ namespace = "default" }): Promise<SelfSubjectRulesReview> {
|
||||
return super.create({}, {
|
||||
spec: {
|
||||
namespace
|
||||
namespace,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -82,7 +82,7 @@ export class SelfSubjectRulesReview extends KubeObject {
|
||||
const separator = apiGroup == "" ? "" : ".";
|
||||
|
||||
return resource + separator + apiGroup;
|
||||
})
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -96,6 +96,6 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
selfSubjectRulesReviewApi
|
||||
selfSubjectRulesReviewApi,
|
||||
};
|
||||
|
||||
|
||||
@ -62,5 +62,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
serviceAccountsApi
|
||||
serviceAccountsApi,
|
||||
};
|
||||
|
||||
@ -53,7 +53,7 @@ export interface Service {
|
||||
clusterIP: string;
|
||||
clusterIPs?: string[];
|
||||
externalTrafficPolicy?: string;
|
||||
externalName: string;
|
||||
externalName?: string;
|
||||
loadBalancerIP?: string;
|
||||
loadBalancerSourceRanges?: string[];
|
||||
sessionAffinity: string;
|
||||
@ -100,11 +100,15 @@ export class Service extends KubeObject {
|
||||
getExternalIps() {
|
||||
const lb = this.getLoadBalancer();
|
||||
|
||||
if (lb && lb.ingress) {
|
||||
if (lb?.ingress) {
|
||||
return lb.ingress.map(val => val.ip || val.hostname);
|
||||
}
|
||||
|
||||
return this.spec.externalIPs || [];
|
||||
if (Array.isArray(this.spec?.externalIPs)) {
|
||||
return this.spec.externalIPs;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
getType() {
|
||||
@ -153,5 +157,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
serviceApi
|
||||
serviceApi,
|
||||
};
|
||||
|
||||
@ -42,14 +42,14 @@ export class StatefulSetApi extends KubeApi<StatefulSet> {
|
||||
return this.request.patch(this.getScaleApiUrl(params), {
|
||||
data: {
|
||||
spec: {
|
||||
replicas
|
||||
}
|
||||
}
|
||||
replicas,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"content-type": "application/merge-patch+json"
|
||||
}
|
||||
"content-type": "application/merge-patch+json",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -162,5 +162,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
statefulSetApi
|
||||
statefulSetApi,
|
||||
};
|
||||
|
||||
@ -72,5 +72,5 @@ if (isClusterPageContext()) {
|
||||
}
|
||||
|
||||
export {
|
||||
storageClassApi
|
||||
storageClassApi,
|
||||
};
|
||||
|
||||
@ -42,8 +42,8 @@ if (typeof window === "undefined") {
|
||||
debug: isDevelopment || isDebugging,
|
||||
}, {
|
||||
headers: {
|
||||
"Host": `localhost:${params.port}`
|
||||
}
|
||||
"Host": `localhost:${params.port}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@ -53,8 +53,8 @@ if (typeof window === "undefined") {
|
||||
debug: isDevelopment || isDebugging,
|
||||
}, {
|
||||
headers: {
|
||||
"Host": window.location.host
|
||||
}
|
||||
"Host": window.location.host,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -62,15 +62,15 @@ if (isClusterPageContext()) {
|
||||
apiKube = new KubeJsonApi({
|
||||
serverAddress: `http://127.0.0.1:${window.location.port}`,
|
||||
apiBase: apiKubePrefix,
|
||||
debug: isDevelopment
|
||||
debug: isDevelopment,
|
||||
}, {
|
||||
headers: {
|
||||
"Host": window.location.host
|
||||
}
|
||||
"Host": window.location.host,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
apiBase,
|
||||
apiKube
|
||||
apiKube,
|
||||
};
|
||||
|
||||
@ -57,12 +57,12 @@ export interface JsonApiConfig {
|
||||
export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
static reqInitDefault: RequestInit = {
|
||||
headers: {
|
||||
"content-type": "application/json"
|
||||
}
|
||||
"content-type": "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
static configDefault: Partial<JsonApiConfig> = {
|
||||
debug: false
|
||||
debug: false,
|
||||
};
|
||||
|
||||
constructor(public readonly config: JsonApiConfig, protected reqInit?: RequestInit) {
|
||||
@ -87,7 +87,7 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
{},
|
||||
this.reqInit,
|
||||
await this.getRequestOptions(),
|
||||
init
|
||||
init,
|
||||
);
|
||||
const { query } = params || {} as P;
|
||||
|
||||
@ -126,7 +126,7 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
{},
|
||||
this.reqInit,
|
||||
await this.getRequestOptions(),
|
||||
init
|
||||
init,
|
||||
);
|
||||
const { data, query } = params || {} as P;
|
||||
|
||||
@ -201,7 +201,7 @@ export class JsonApi<D = JsonApiData, P extends JsonApiParams = JsonApiParams> {
|
||||
protected writeLog(log: JsonApiLog) {
|
||||
const { method, reqUrl, ...params } = log;
|
||||
|
||||
logger.info(`[JSON-API] request ${method} ${reqUrl}`, params);
|
||||
logger.debug(`[JSON-API] request ${method} ${reqUrl}`, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -123,13 +123,13 @@ export function forCluster<T extends KubeObject>(cluster: ILocalKubeApiConfig, k
|
||||
debug: isDevelopment,
|
||||
}, {
|
||||
headers: {
|
||||
"Host": `${cluster.metadata.uid}.localhost:${url.port}`
|
||||
}
|
||||
"Host": `${cluster.metadata.uid}.localhost:${url.port}`,
|
||||
},
|
||||
});
|
||||
|
||||
return new KubeApi({
|
||||
objectConstructor: kubeClass,
|
||||
request
|
||||
request,
|
||||
});
|
||||
}
|
||||
|
||||
@ -166,15 +166,15 @@ export function forRemoteCluster<T extends KubeObject>(config: IRemoteKubeApiCon
|
||||
...(token ? {
|
||||
getRequestOptions: async () => ({
|
||||
headers: {
|
||||
"Authorization": `Bearer ${isFunction(token) ? await token() : token}`
|
||||
}
|
||||
})
|
||||
} : {})
|
||||
"Authorization": `Bearer ${isFunction(token) ? await token() : token}`,
|
||||
},
|
||||
}),
|
||||
} : {}),
|
||||
}, reqInit);
|
||||
|
||||
return new KubeApi({
|
||||
objectConstructor: kubeClass,
|
||||
request
|
||||
request,
|
||||
});
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ export class KubeApi<T extends KubeObject> {
|
||||
objectConstructor,
|
||||
request = apiKube,
|
||||
kind = options.objectConstructor?.kind,
|
||||
isNamespaced = options.objectConstructor?.namespaced
|
||||
isNamespaced = options.objectConstructor?.namespaced,
|
||||
} = options || {};
|
||||
|
||||
if (!options.apiBase) {
|
||||
@ -292,7 +292,7 @@ export class KubeApi<T extends KubeObject> {
|
||||
|
||||
return {
|
||||
apiPrefix: this.apiPrefix,
|
||||
apiGroup: this.apiGroup
|
||||
apiGroup: this.apiGroup,
|
||||
};
|
||||
}
|
||||
|
||||
@ -306,10 +306,10 @@ export class KubeApi<T extends KubeObject> {
|
||||
|
||||
// The apiPrefix and apiGroup might change due to fallbackApiBases, so we must override them
|
||||
Object.defineProperty(this, "apiPrefix", {
|
||||
value: apiPrefix
|
||||
value: apiPrefix,
|
||||
});
|
||||
Object.defineProperty(this, "apiGroup", {
|
||||
value: apiGroup
|
||||
value: apiGroup,
|
||||
});
|
||||
|
||||
const res = await this.request.get<IKubePreferredVersion>(`${this.apiPrefix}/${this.apiGroup}`);
|
||||
@ -444,9 +444,9 @@ export class KubeApi<T extends KubeObject> {
|
||||
apiVersion: this.apiVersionWithGroup,
|
||||
metadata: {
|
||||
name,
|
||||
namespace
|
||||
}
|
||||
}, data)
|
||||
namespace,
|
||||
},
|
||||
}, data),
|
||||
});
|
||||
const parsed = this.parseResponse(res);
|
||||
|
||||
|
||||
@ -317,7 +317,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
|
||||
protected bindWatchEventsUpdater(delay = 1000) {
|
||||
reaction(() => this.eventsBuffer.length, this.updateFromEventsBuffer, {
|
||||
delay
|
||||
delay,
|
||||
});
|
||||
}
|
||||
|
||||
@ -352,7 +352,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
const watch = () => this.api.watch({
|
||||
namespace,
|
||||
abortController,
|
||||
callback
|
||||
callback,
|
||||
});
|
||||
|
||||
const { signal } = abortController;
|
||||
@ -375,8 +375,8 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
|
||||
timedRetry = setTimeout(() => {
|
||||
(
|
||||
namespace
|
||||
? this.loadAll({ namespaces: [namespace], reqInit: { signal } })
|
||||
: this.loadAll({ merge: false, reqInit: { signal } })
|
||||
? this.loadAll({ namespaces: [namespace], reqInit: { signal }})
|
||||
: this.loadAll({ merge: false, reqInit: { signal }})
|
||||
).then(watch);
|
||||
}, 1000);
|
||||
} else if (error) { // not sure what to do, best to retry
|
||||
|
||||
@ -82,7 +82,7 @@ export class KubeWatchApi {
|
||||
}
|
||||
|
||||
subscribeStores(stores: KubeObjectStore<KubeObject>[], opts: IKubeWatchSubscribeStoreOptions = {}): Disposer {
|
||||
const { preload = true, waitUntilLoaded = true, loadOnce = false, } = opts;
|
||||
const { preload = true, waitUntilLoaded = true, loadOnce = false } = opts;
|
||||
const subscribingNamespaces = opts.namespaces ?? this.context?.allNamespaces ?? [];
|
||||
const unsubscribeList: Function[] = [];
|
||||
let isUnsubscribed = false;
|
||||
@ -134,7 +134,7 @@ export class KubeWatchApi {
|
||||
};
|
||||
}
|
||||
|
||||
protected log({ message, cssStyle = "", meta = {} }: IKubeWatchLog) {
|
||||
protected log({ message, cssStyle = "", meta = {}}: IKubeWatchLog) {
|
||||
if (isProduction && !isDebugging) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ function loadToOptions(rawYaml: string): OptionsResult {
|
||||
allowUnknown: true,
|
||||
stripUnknown: {
|
||||
arrays: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
const {
|
||||
clusters: rawClusters,
|
||||
@ -210,16 +210,16 @@ export function dumpConfigYaml(kubeConfig: Partial<KubeConfig>): string {
|
||||
"certificate-authority-data": cluster.caData,
|
||||
"certificate-authority": cluster.caFile,
|
||||
server: cluster.server,
|
||||
"insecure-skip-tls-verify": cluster.skipTLSVerify
|
||||
}
|
||||
"insecure-skip-tls-verify": cluster.skipTLSVerify,
|
||||
},
|
||||
}));
|
||||
const contexts = kubeConfig.contexts.map(context => ({
|
||||
name: context.name,
|
||||
context: {
|
||||
cluster: context.cluster,
|
||||
user: context.user,
|
||||
namespace: context.namespace
|
||||
}
|
||||
namespace: context.namespace,
|
||||
},
|
||||
}));
|
||||
const users = kubeConfig.users.map(user => ({
|
||||
name: user.name,
|
||||
@ -232,8 +232,8 @@ export function dumpConfigYaml(kubeConfig: Partial<KubeConfig>): string {
|
||||
exec: user.exec,
|
||||
token: user.token,
|
||||
username: user.username,
|
||||
password: user.password
|
||||
}
|
||||
password: user.password,
|
||||
},
|
||||
}));
|
||||
const config = {
|
||||
apiVersion: "v1",
|
||||
|
||||
@ -56,7 +56,7 @@ if (ipcMain) {
|
||||
},
|
||||
}),
|
||||
),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
if (!isTestEnv) {
|
||||
@ -73,7 +73,7 @@ if (ipcMain) {
|
||||
maxsize: 16 * 1024,
|
||||
maxFiles: 16,
|
||||
tailable: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -23,7 +23,7 @@ import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
|
||||
export const addClusterRoute: RouteProps = {
|
||||
path: "/add-cluster"
|
||||
path: "/add-cluster",
|
||||
};
|
||||
|
||||
export const addClusterURL = buildURL(addClusterRoute.path);
|
||||
|
||||
@ -27,7 +27,7 @@ export interface CatalogViewRouteParam {
|
||||
kind?: string;
|
||||
}
|
||||
export const catalogRoute: RouteProps = {
|
||||
path: "/catalog/:group?/:kind?"
|
||||
path: "/catalog/:group?/:kind?",
|
||||
};
|
||||
|
||||
export const getPreviousTabUrl = (path: string) => {
|
||||
@ -36,8 +36,8 @@ export const getPreviousTabUrl = (path: string) => {
|
||||
return catalogURL({
|
||||
params: {
|
||||
group: group || browseCatalogTab,
|
||||
kind
|
||||
}
|
||||
kind,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../utils/buildUrl";
|
||||
|
||||
export const clusterRoute: RouteProps = {
|
||||
path: "/overview"
|
||||
path: "/overview",
|
||||
};
|
||||
|
||||
export const clusterURL = buildURL(clusterRoute.path);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user