├── .eslintignore
├── .eslintrc
├── .gitignore
├── .prettierrc
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── config-overrides.js
├── cypress.json
├── docs
└── images
│ └── dashboard-ui.png
├── nginx.config
├── package-lock.json
├── package.json
├── public
├── favicon.png
├── index.html
├── logo.png
├── manifest.json
└── robots.txt
├── src
├── components
│ ├── ClusterFeatureModal.tsx
│ ├── CodeMirrorEditor.tsx
│ ├── Layout.css
│ ├── Layout.tsx
│ └── YamlModal.tsx
├── configs
│ └── menu.ts
├── index.css
├── index.tsx
├── languages
│ ├── i18n.ts
│ ├── locales
│ │ ├── en-US
│ │ │ └── en-US.json
│ │ └── zh-CN
│ │ │ └── zh-CN.json
│ └── supportedLocales.ts
├── logo.png
├── models
│ └── menu.ts
├── pages
│ ├── app
│ │ ├── App.css
│ │ └── App.tsx
│ ├── backup
│ │ ├── Backup.tsx
│ │ └── index.ts
│ ├── cluster
│ │ ├── Add.tsx
│ │ ├── Cluster.tsx
│ │ ├── Create.tsx
│ │ ├── Update.tsx
│ │ └── index.ts
│ ├── login
│ │ ├── Login.tsx
│ │ ├── ResetPassword.tsx
│ │ └── index.ts
│ ├── monitor
│ │ ├── Monitor.tsx
│ │ └── index.ts
│ └── visualization
│ │ ├── Visualization.tsx
│ │ └── index.ts
├── react-app-env.d.ts
├── reportWebVitals.ts
├── setupProxy.js
├── setupTests.ts
└── utils
│ ├── common.ts
│ ├── cookies.ts
│ ├── fromHelper.ts
│ └── http.ts
├── tsconfig.json
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | **.log
3 | **.lock
4 | tsconfig.json
5 | build/*
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@typescript-eslint/parser",
3 | "extends": ["plugin:@typescript-eslint/recommended", "react-app"],
4 | "plugins": ["@typescript-eslint", "react"],
5 | "rules": {
6 | "no-restricted-globals": 1,
7 | "@typescript-eslint/ban-types": 1,
8 | "prefer-const": 1,
9 | "@typescript-eslint/no-var-requires": 1,
10 | "@typescript-eslint/no-inferrable-types": 1,
11 | "@typescript-eslint/no-empty-function": 1,
12 | "@typescript-eslint/no-empty-interface": 1,
13 | "@typescript-eslint/no-this-alias": 1,
14 | "@typescript-eslint/no-explicit-any": 0,
15 | "prefer-spread": 1,
16 | "prefer-rest-params": 1,
17 | "@typescript-eslint/triple-slash-reference": 1
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 | node_modules
3 | scripts/flow/*/.flowconfig
4 | .flowconfig
5 | *~
6 | *.pyc
7 | .grunt
8 | _SpecRunner.html
9 | __benchmarks__
10 | build/
11 | remote-repo/
12 | coverage/
13 | .module-cache
14 | fixtures/dom/public/react-dom.js
15 | fixtures/dom/public/react.js
16 | test/the-files-to-test.generated.js
17 | *.log*
18 | chrome-user-data
19 | *.sublime-project
20 | *.sublime-workspace
21 | .idea
22 | *.iml
23 | .vscode
24 | *.swp
25 | *.swo
26 |
27 | packages/react-devtools-core/dist
28 | packages/react-devtools-extensions/chrome/build
29 | packages/react-devtools-extensions/chrome/*.crx
30 | packages/react-devtools-extensions/chrome/*.pem
31 | packages/react-devtools-extensions/firefox/build
32 | packages/react-devtools-extensions/firefox/*.xpi
33 | packages/react-devtools-extensions/firefox/*.pem
34 | packages/react-devtools-extensions/shared/build
35 | packages/react-devtools-extensions/.tempUserDataDir
36 | packages/react-devtools-inline/dist
37 | packages/react-devtools-shell/dist
38 | packages/react-devtools-timeline/dist
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all",
4 | "printWidth": 80,
5 | "overrides": [
6 | {
7 | "files": ".prettierrc",
8 | "options": { "parser": "json" }
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ## [0.5.0](https://git.woa.com/etcd/kstone-dashboard/compare/v0.4.0...v0.5.0) (2021-12-08)
6 |
7 | ## [0.4.0](https://git.woa.com/etcd/kstone-dashboard/compare/v0.3.0...v0.4.0) (2021-12-08)
8 |
9 | ## [0.3.0](https://git.woa.com/etcd/kstone-dashboard/compare/v0.2.3...v0.3.0) (2021-12-08)
10 |
11 | ### [0.2.3](https://git.woa.com/etcd/kstone-dashboard/compare/v0.2.2...v0.2.3) (2021-12-08)
12 |
13 | ### [0.2.2](https://git.woa.com/etcd/kstone-dashboard/compare/v0.2.1...v0.2.2) (2021-12-08)
14 |
15 | ### [0.2.1](https://git.woa.com/etcd/kstone-dashboard/compare/v0.2.0...v0.2.1) (2021-12-08)
16 |
17 | ## [0.2.0](https://git.woa.com/etcd/kstone-dashboard/compare/v0.1.6...v0.2.0) (2021-12-08)
18 |
19 | ### [0.1.6](https://git.woa.com/etcd/kstone-dashboard/compare/v0.1.5...v0.1.6) (2021-12-08)
20 |
21 | ### [0.1.5](https://git.woa.com/etcd/kstone-dashboard/compare/v0.1.4...v0.1.5) (2021-12-08)
22 |
23 | ### [0.1.4](https://git.woa.com/etcd/kstone-dashboard/compare/v0.1.3...v0.1.4) (2021-12-08)
24 |
25 | ### 0.1.3 (2021-12-08)
26 |
27 |
28 | ### Bug Fixes
29 |
30 | * 监控和巡检 ([1d2c59a](https://git.woa.com/etcd/kstone-dashboard/commit/1d2c59a8f819cf76904684e8d687c53e17727d0c))
31 | * add eslint && lint code ([e2061cd](https://git.woa.com/etcd/kstone-dashboard/commit/e2061cdb3e5e048c55d6042fe243ccc1c6add33c))
32 | * format & add comment ([4c983f0](https://git.woa.com/etcd/kstone-dashboard/commit/4c983f0661e171e6858c765a68541e78d3883c03))
33 | * update logo ([686513a](https://git.woa.com/etcd/kstone-dashboard/commit/686513afc64f4270165524515677240adaaad6f5))
34 | * use new log ([5219263](https://git.woa.com/etcd/kstone-dashboard/commit/5219263bc4db9bc06b92f2692c1628ebbe35f4b0))
35 |
36 | ### [0.1.2](https://github.com/tkestack/kstone-dashboard/kstone-dashboard/compare/v0.1.1...v0.1.2) (2021-11-25)
37 |
38 |
39 | ### Bug Fixes
40 |
41 | * lint ([ddae85b](https://github.com/tkestack/kstone-dashboard/kstone-dashboard/commit/ddae85b605d7a51593bbafd52f974b8e9877f21b))
42 |
43 | ### 0.1.1 (2021-11-25)
44 |
45 |
46 | ### Bug Fixes
47 |
48 | * add eslint && lint code ([e2061cd](https://github.com/tkestack/kstone-dashboard/kstone-dashboard/commit/e2061cdb3e5e048c55d6042fe243ccc1c6add33c))
49 | * add standard-version ([f8c8b44](https://github.com/tkestack/kstone-dashboard/kstone-dashboard/commit/f8c8b448c5e50abb572c2d5bf384c1eec7a4321a))
50 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.13.0-alpine as build-deps
2 | WORKDIR /usr/src/app
3 | COPY package.json yarn.lock ./
4 | RUN yarn
5 | COPY . ./
6 | RUN export NODE_OPTIONS="--max-old-space-size=8192"; yarn build
7 |
8 | FROM nginx:1.21.3-alpine
9 | ADD ./nginx.config /etc/nginx/conf.d/default.conf
10 | COPY --from=build-deps /usr/src/app/build /usr/share/nginx/html
11 | EXPOSE 80
12 | CMD ["nginx", "-g", "daemon off;"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | PROJECT := "kstone-dashboard"
2 | DOCKERDIR := "."
3 | RegistryNamespace := "tkestack"
4 | IMAGE := ${RegistryNamespace}/${PROJECT}
5 |
6 | TAG := $(shell git describe --dirty --always --tags)
7 | IMAGEID := ${IMAGE}:${TAG}
8 |
9 | .PHONY: build
10 | build:
11 | @docker build --network=host --no-cache -t ${IMAGEID} -f ${DOCKERDIR}/Dockerfile ${DOCKERDIR}
12 |
13 | .PHONY: push
14 | push: build
15 | @docker push ${IMAGEID}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Kstone Dashboard
2 |
3 | Kstone Dashboard is a web-based UI for managing Kstone. It can help users to manage etcd based kstone and enjoy monitoring, inspection, visualization, backup and other features.
4 |
5 | 
6 |
7 | ## Getting Started
8 |
9 | ### Install
10 |
11 | Please read [detailed install document](https://github.com/tkestack/kstone/blob/master/charts/install.md),
12 | You can quickly install kstone through HELM.
13 |
14 | ### Develope
15 |
16 | ``` shell
17 | yarn
18 | yarn start
19 | ```
20 |
21 | ### Build
22 |
23 | ``` shell
24 | make build
25 | ```
26 |
27 | ### Push Image
28 |
29 | ``` shell
30 | make push
31 | ```
32 |
33 | ## Community
34 |
35 | * You are encouraged to communicate most things via GitHub [issues](https://github.com/tkestack/kstone-dashboard/issues/new/choose) or [pull requests](https://github.com/tkestack/kstone-dashboard/pulls).
36 |
37 | ## Licensing
38 |
39 | Kstone is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
--------------------------------------------------------------------------------
/config-overrides.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
20 |
21 | module.exports = function override(config, env) {
22 | config.plugins.push(new MonacoWebpackPlugin({
23 | languages: ['json', 'javascript', 'yaml']
24 | }));
25 | return config;
26 | }
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/docs/images/dashboard-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kstone-io/kstone-dashboard/73eb1bdb253de71c4f96fca907523c6f75a44f52/docs/images/dashboard-ui.png
--------------------------------------------------------------------------------
/nginx.config:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name _;
4 |
5 | root /usr/share/nginx/html;
6 | index index.html;
7 |
8 | location / {
9 | try_files $uri /index.html;
10 | }
11 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kstone-dashboard",
3 | "version": "0.0.1",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "@types/jest": "^26.0.15",
10 | "@types/js-cookie": "^3.0.1",
11 | "@types/js-yaml": "^4.0.4",
12 | "@types/lodash": "^4.14.176",
13 | "@types/node": "^12.0.0",
14 | "@types/react": "^17.0.0",
15 | "@types/react-dom": "^17.0.0",
16 | "@types/react-router-dom": "^5.3.2",
17 | "@types/validator": "^13.6.6",
18 | "antd": "^4.17.0-alpha.9",
19 | "axios": "^0.24.0",
20 | "codemirror": "^5.63.3",
21 | "final-form": "^4.20.4",
22 | "history": "5",
23 | "http-proxy-middleware": "^2.0.1",
24 | "i18next": "^21.6.3",
25 | "i18next-browser-languagedetector": "^6.1.2",
26 | "js-base64": "^3.7.2",
27 | "js-cookie": "^3.0.1",
28 | "js-yaml": "^4.1.0",
29 | "lodash": "^4.17.21",
30 | "monaco-editor": "^0.29.1",
31 | "monaco-editor-webpack-plugin": "^5.0.0",
32 | "prop-types": "^15.7.2",
33 | "react": "^17.0.2",
34 | "react-codemirror2": "^7.2.1",
35 | "react-dom": "^17.0.2",
36 | "react-final-form-hooks": "^2.0.2",
37 | "react-i18next": "^11.15.1",
38 | "react-monaco-editor": "^0.46.0",
39 | "react-router-dom": "6",
40 | "react-scripts": "4.0.3",
41 | "standard-version": "^9.3.2",
42 | "typescript": "^4.1.2",
43 | "validator": "^13.7.0",
44 | "web-vitals": "^1.0.1"
45 | },
46 | "scripts": {
47 | "start": "react-app-rewired start",
48 | "build": "react-app-rewired build",
49 | "test": "react-app-rewired test",
50 | "eject": "react-app-rewired eject",
51 | "release": "standard-version"
52 | },
53 | "eslintConfig": {
54 | "extends": [
55 | "react-app",
56 | "react-app/jest"
57 | ]
58 | },
59 | "browserslist": {
60 | "production": [
61 | ">0.2%",
62 | "not dead",
63 | "not op_mini all"
64 | ],
65 | "development": [
66 | "last 1 chrome version",
67 | "last 1 firefox version",
68 | "last 1 safari version"
69 | ]
70 | },
71 | "devDependencies": {
72 | "@types/react-helmet": "^6.1.5",
73 | "@typescript-eslint/eslint-plugin": "^5.4.0",
74 | "@typescript-eslint/parser": "^5.4.0",
75 | "babel-eslint": "^10.1.0",
76 | "cypress": "^9.0.0",
77 | "eslint": "^7.11.0",
78 | "eslint-config-react-app": "^6.0.0",
79 | "eslint-loader": "^4.0.2",
80 | "eslint-plugin-flowtype": "^8.0.3",
81 | "eslint-plugin-import": "^2.25.3",
82 | "eslint-plugin-jsx-a11y": "^6.5.1",
83 | "eslint-plugin-react": "^7.27.1",
84 | "eslint-plugin-react-hooks": "^4.3.0",
85 | "lint-staged": "^12.1.2",
86 | "react-app-rewired": "^2.1.8"
87 | },
88 | "license": "Apache-2.0"
89 | }
90 |
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kstone-io/kstone-dashboard/73eb1bdb253de71c4f96fca907523c6f75a44f52/public/favicon.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
35 |
36 |
45 | Kstone
46 |
47 |
48 |
49 |
50 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kstone-io/kstone-dashboard/73eb1bdb253de71c4f96fca907523c6f75a44f52/public/logo.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "kstone",
3 | "name": "kstone",
4 | "icons": [
5 | {
6 | "src": "favicon.png",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/components/ClusterFeatureModal.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | import { Modal, Form, Card, Input, Switch, Spin, InputNumber, Row, Col } from 'antd';
20 | import { useEffect, useState } from 'react';
21 | import * as _ from 'lodash';
22 | import http from 'src/utils/http';
23 | import { encode, decode } from 'js-base64';
24 | import { useTranslation } from 'react-i18next';
25 | import { GenerateOwnerReferences } from 'src/utils/common';
26 |
27 | // form style
28 | const formItemLayout = {
29 | labelCol: { span: 10 },
30 | wrapperCol: { span: 12 },
31 | };
32 |
33 | const FeatureGatesKey = 'featureGates';
34 | // page to edit feature gates
35 | export const ClusterFeatureModal = ({
36 | visible,
37 | data,
38 | close,
39 | }: {
40 | visible: any;
41 | data: any;
42 | close: any;
43 | }): JSX.Element => {
44 | const [isLoading, setIsLoading] = useState(false);
45 | const { t } = useTranslation();
46 | const [featureMap, setFeatureMap] = useState({} as any);
47 |
48 | const [form] = Form.useForm();
49 |
50 | const generateFeatureAnnotation = (): string => {
51 | let result = '';
52 | Object.keys(featureMap).sort().map((feature: string) => {
53 | result += `${feature}=${featureMap[feature].toString()},`;
54 | return feature;
55 | });
56 | return result.substring(0, result.lastIndexOf(','));
57 | };
58 |
59 | // load info
60 | useEffect(() => {
61 | setIsLoading(true);
62 | http.get('/apis/features').then(featureResp => {
63 | (async () => {
64 | if (data?.metadata?.labels) {
65 | const map: any = {};
66 | featureResp.data.map((item: string) => {
67 | map[item] = (data.metadata.labels[item] === 'true');
68 | return item;
69 | });
70 | setFeatureMap(map);
71 |
72 | if (data.metadata.labels.backup === 'true') {
73 | const backupValue = JSON.parse(
74 | data?.metadata?.annotations?.backup ?? '{}',
75 | );
76 | const res = await http.get(`/apis/secrets/cos-${data.metadata.name}`);
77 | form.setFieldsValue({
78 | backupIntervalInSecond: backupValue?.backupPolicy?.backupIntervalInSecond,
79 | maxBackups: backupValue?.backupPolicy?.maxBackups,
80 | timeoutInSecond: backupValue?.backupPolicy?.timeoutInSecond,
81 | secretId: decode(res?.data?.data['secret-id'] ?? ''),
82 | secretKey: decode(res?.data?.data['secret-key'] ?? ''),
83 | path: backupValue?.cos?.path
84 | });
85 | }
86 | setIsLoading(false);
87 | }
88 | })();
89 | });
90 | }, [data, form]);
91 | // handle finish
92 | const onFinish = (values: any) => {
93 | const backupInfo = {
94 | backupIntervalInSecond: values.backupIntervalInSecond,
95 | maxBackups: values.maxBackups,
96 | timeoutInSecond: values.timeoutInSecond,
97 | secretId: values.secretId,
98 | secretKey: values.secretKey,
99 | path: values.path,
100 | };
101 |
102 | updateCluster(backupInfo);
103 | createSecret(backupInfo);
104 | close();
105 | };
106 | // update feature gates setting
107 | const updateCluster = async (values?: any) => {
108 | const model = _.cloneDeep(data);
109 | if (values && featureMap['backup']) {
110 | const backup = `
111 | {
112 | "backupPolicy": {
113 | "backupIntervalInSecond": ${values.backupIntervalInSecond},
114 | "maxBackups": ${values.maxBackups},
115 | "timeoutInSecond": ${values.timeoutInSecond}
116 | },
117 | "cos": {
118 | "cosSecret": "cos-${data.metadata.name}",
119 | "path": "${values.path}"
120 | },
121 | "storageType": "COS"
122 | }
123 | `;
124 | model.metadata.annotations.backup = backup;
125 | }
126 | const gates = generateFeatureAnnotation();
127 | model.metadata.annotations[FeatureGatesKey] = gates;
128 | await http.put(`/apis/etcdclusters/${data.metadata.name}`, model);
129 | };
130 | // create secret for cos
131 | const createSecret = async (values: any) => {
132 | if (!featureMap['backup']) {
133 | return;
134 | }
135 | const model = {
136 | apiVersion: 'v1',
137 | data: {
138 | 'secret-id': encode(values.secretId),
139 | 'secret-key': encode(values.secretKey),
140 | },
141 | kind: 'Secret',
142 | metadata: {
143 | name: `cos-${data.metadata.name}`,
144 | ownerReferences: GenerateOwnerReferences(data.metadata.name, data.metadata.uid),
145 | },
146 | type: 'Opaque',
147 | };
148 | http
149 | .get(`/apis/secrets/cos-${data.metadata.name}`)
150 | .then((resp) => {
151 | if (resp.data.code === 404) {
152 | http.post('/apis/secrets', model);
153 | } else {
154 | http.put(`/apis/secrets/cos-${data.metadata.name}`, model);
155 | }
156 | })
157 | .catch(() => {
158 | http.post('/apis/secrets', model);
159 | });
160 | };
161 |
162 | return (
163 |
169 |
276 |
277 | );
278 | };
279 |
--------------------------------------------------------------------------------
/src/components/CodeMirrorEditor.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | import { insertCSS } from '../../src/utils/common';
20 | import * as React from 'react';
21 | import { UnControlled as CodeMirror } from 'react-codemirror2';
22 |
23 | // 这里是对editor一些配置
24 | require('codemirror/mode/yaml/yaml');
25 |
26 | insertCSS(
27 | 'YamlEditorPanel',
28 | `
29 | .cm-s-monokai.CodeMirror{background:#272822;color:#f8f8f2;height:100%;}.cm-s-monokai div.CodeMirror-selected{background:#49483e}.cm-s-monokai .CodeMirror-line::selection,.cm-s-monokai .CodeMirror-line>span::selection,.cm-s-monokai .CodeMirror-line>span>span::selection{background:rgba(73,72,62,.99)}.cm-s-monokai .CodeMirror-line::-moz-selection,.cm-s-monokai .CodeMirror-line>span::-moz-selection,.cm-s-monokai .CodeMirror-line>span>span::-moz-selection{background:rgba(73,72,62,.99)}.cm-s-monokai .CodeMirror-gutters{background:#272822;border-right:0}.cm-s-monokai .CodeMirror-guttermarker{color:white}.cm-s-monokai .CodeMirror-guttermarker-subtle{color:#d0d0d0}.cm-s-monokai .CodeMirror-linenumber{color:#d0d0d0}.cm-s-monokai .CodeMirror-cursor{border-left:1px solid #f8f8f0}.cm-s-monokai span.cm-comment{color:#75715e}.cm-s-monokai span.cm-atom{color:#ae81ff}.cm-s-monokai span.cm-number{color:#ae81ff}.cm-s-monokai span.cm-property,.cm-s-monokai span.cm-attribute{color:#a6e22e}.cm-s-monokai span.cm-keyword{color:#f92672}.cm-s-monokai span.cm-builtin{color:#66d9ef}.cm-s-monokai span.cm-string{color:#e6db74}.cm-s-monokai span.cm-variable{color:#f8f8f2}.cm-s-monokai span.cm-variable-2{color:#9effff}.cm-s-monokai span.cm-variable-3,.cm-s-monokai span.cm-type{color:#66d9ef}.cm-s-monokai span.cm-def{color:#fd971f}.cm-s-monokai span.cm-bracket{color:#f8f8f2}.cm-s-monokai span.cm-tag{color:#f92672}.cm-s-monokai span.cm-header{color:#ae81ff}.cm-s-monokai span.cm-link{color:#ae81ff}.cm-s-monokai span.cm-error{background:#f92672;color:#f8f8f0}.cm-s-monokai .CodeMirror-activeline-background{background:#373831}.cm-s-monokai .CodeMirror-matchingbracket{text-decoration:underline;color:white!important}.CodeMirror{font-family:monospace;height:560px;color:black;border-radius:2px;direction:ltr}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{background-color:white}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.CodeMirror-guttermarker{color:black}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror-cursor{border-left:1px solid black;border-right:0;width:0}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.cm-fat-cursor .CodeMirror-cursor{width:auto;border:0!important;background:#7e7}.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite;background-color:#7e7}@-moz-keyframes blink{50%{background-color:transparent}}@-webkit-keyframes blink{50%{background-color:transparent}}@keyframes blink{50%{background-color:transparent}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-rulers{position:absolute;left:0;right:0;top:-50px;bottom:-20px;overflow:hidden}.CodeMirror-ruler{border-left:1px solid #ccc;top:0;bottom:0;position:absolute}.cm-s-default .cm-header{color:blue}.cm-s-default .cm-quote{color:#090}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:bold}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3,.cm-s-default .cm-type{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta{color:#555}.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-s-default .cm-error{color:#f00}.cm-invalidchar{color:#f00}.CodeMirror-composing{border-bottom:2px solid}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{position:relative;overflow:hidden;background:white}.CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative}.CodeMirror-sizer{position:relative;border-right:30px solid transparent}.CodeMirror-vscrollbar,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;min-height:100%;z-index:3}
30 | .CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;vertical-align:top;margin-bottom:-30px}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-gutter-wrapper ::selection{background-color:transparent}.CodeMirror-gutter-wrapper ::-moz-selection{background-color:transparent}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent;-webkit-font-variant-ligatures:contextual;font-variant-ligatures:contextual}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-rtl pre{direction:rtl}.CodeMirror-code{outline:0}.CodeMirror-scroll,.CodeMirror-sizer,.CodeMirror-gutter,.CodeMirror-gutters,.CodeMirror-linenumber{-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-cursor{position:absolute;pointer-events:none}.CodeMirror-measure pre{position:static}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}div.CodeMirror-dragcursors{visibility:visible}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.CodeMirror-line::selection,.CodeMirror-line>span::selection,.CodeMirror-line>span>span::selection{background:#d7d4f0}.CodeMirror-line::-moz-selection,.CodeMirror-line>span::-moz-selection,.CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.cm-searching{background-color:#ffa;background-color:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0}
31 | .codeMirrorHeight{height:600px;overflow:auto;}
32 | `,
33 | );
34 |
35 | interface YamlEditorPanelProps {
36 | /** 输入的内容 */
37 | config?: string;
38 |
39 | /** 是否只读 */
40 | readOnly?: boolean;
41 |
42 | /** 回调函数,处理输入数据 */
43 | handleInputForEditor?: (config: string) => void;
44 |
45 | /** 当前的mode */
46 | mode?: string;
47 | }
48 |
49 | export class YamlEditorPanel extends React.Component {
50 | render(): JSX.Element {
51 | const { readOnly, mode = 'yaml', handleInputForEditor } = this.props;
52 |
53 | const codeOptions = {
54 | lineNumbers: true,
55 | mode,
56 | theme: 'monokai',
57 | readOnly: readOnly ? readOnly : false,
58 | lineWrapping: true, // 自动换行
59 | styleActiveLine: true, // 当前行背景高亮
60 | };
61 |
62 | return (
63 | {
68 | !readOnly &&
69 | handleInputForEditor !== undefined &&
70 | handleInputForEditor(value);
71 | }}
72 | />
73 | );
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/components/Layout.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | .logo {
20 | float: left;
21 | margin: 0px 10px;
22 | padding: 0px 50px 0 0px;
23 | width: 100%;
24 | display: flex;
25 | justify-content: space-between;
26 | align-items: center;
27 | }
28 |
29 | .site-layout .site-layout-background {
30 | background: #fff;
31 | }
--------------------------------------------------------------------------------
/src/components/Layout.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | import { useState } from 'react';
20 | import { Outlet, Link } from 'react-router-dom';
21 | import {
22 | ConfigProvider,
23 | Dropdown,
24 | Layout as AntdLayout,
25 | Menu,
26 | Button,
27 | } from 'antd';
28 | import { ClusterOutlined } from '@ant-design/icons';
29 | import logo from '../../src/logo.png';
30 | import './Layout.css';
31 | import DownOutlined from '@ant-design/icons/lib/icons/DownOutlined';
32 | import { useTranslation } from 'react-i18next';
33 | import zhCN from 'antd/lib/locale/zh_CN';
34 | import enUS from 'antd/lib/locale/en_US';
35 | import cookies from 'src/utils/cookies';
36 | import { t } from 'i18next';
37 |
38 | const { Header, Content, Sider } = AntdLayout;
39 | const { SubMenu } = Menu;
40 |
41 | const Layout = ({ menu }: { menu: any }): JSX.Element => {
42 | const [collapsed, setCollapsed] = useState(false);
43 | const { i18n } = useTranslation();
44 | const lang = localStorage.getItem('locale');
45 |
46 | const handleMenuClick = (e: any) => {
47 | if (e.key === '1') {
48 | i18n.changeLanguage('zh-CN');
49 | localStorage.setItem('locale', 'zh-CN');
50 | }
51 | if (e.key === '2') {
52 | i18n.changeLanguage('en-US');
53 | localStorage.setItem('locale', 'en-US');
54 | }
55 | window.location.reload();
56 | };
57 |
58 | const handleLogout = () => {
59 | cookies.remove("token");
60 | window.location.href = "/login";
61 | };
62 |
63 | const menus = (
64 |
68 | );
69 |
70 | return (
71 |
72 |
73 |
185 |
186 |
187 | );
188 | }
--------------------------------------------------------------------------------
/src/pages/login/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | export * from './Login';
20 | export * from './ResetPassword';
21 |
--------------------------------------------------------------------------------
/src/pages/monitor/Monitor.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Tencent is pleased to support the open source community by making TKEStack
3 | * available.
4 | *
5 | * Copyright (C) 2012-2023 Tencent. All Rights Reserved.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8 | * this file except in compliance with the License. You may obtain a copy of the
9 | * License at
10 | *
11 | * https://opensource.org/licenses/Apache-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OF ANY KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations under the License.
17 | */
18 |
19 | import { useEffect } from 'react';
20 | import { Layout, Typography, Select, Empty } from 'antd';
21 | import { useState } from 'react';
22 |
23 | import http from 'src/utils/http';
24 | import { useTranslation } from 'react-i18next';
25 |
26 | const { Text } = Typography;
27 | const { Header, Content } = Layout;
28 |
29 | const GrafanaUrl =
30 | '/grafana/d/Hw7tu7aZz123123/kstone?var-datasource=KSTONE-PROM&theme=light&kiosk=tv&orgId=1&var-job=';
31 |
32 | export function Monitor(): JSX.Element {
33 | const [grafanaUrl, setGrafanaUrl] = useState('');
34 | const [clusterList, setClusterList] = useState([]);
35 | const [clusterName, setClusterName] = useState('');
36 | const [cluster, setCluster] = useState({} as any);
37 | const { t } = useTranslation();
38 |
39 | const getEtcdCluster = async () => {
40 | http.get('/apis/etcdclusters').then((resp) => {
41 | if (resp.data.items.length) {
42 | setClusterList(resp.data.items);
43 | setClusterName(resp.data.items[0].metadata.name);
44 | setCluster(resp.data.items[0]);
45 | setGrafanaUrl(`${GrafanaUrl}${resp.data.items[0].metadata.name}`);
46 | }
47 | });
48 | };
49 |
50 | useEffect(() => {
51 | getEtcdCluster();
52 | }, []);
53 |
54 | return (
55 |
60 |
61 |
65 | {t('ClusterMonitor')}:
66 |
67 |
97 |
98 |
108 |