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