Compare commits

...

30 Commits
v0.1.0 ... main

Author SHA1 Message Date
KubeEdge Bot cd2854e901
Merge pull request #63 from ghosind/apply-reviewer
Apply to be a reviewer
2025-07-22 14:32:57 +08:00
Chen Su f6c70e933b
Sort reviewer list alphabetically
Signed-off-by: Chen Su <ghosind@gmail.com>
2025-07-22 08:56:26 +08:00
KubeEdge Bot 89f6eb0ec5
Merge pull request #62 from Spiral-Memory/fix/nav_btn_click_minimal
fix: making full menu item clickable
2025-07-21 20:26:56 +08:00
Zishan Ahmad cba5fab30c used React.ElementType
Signed-off-by: Zishan Ahmad <zishan.barun@gmail.com>
2025-07-20 21:00:10 +05:30
Zishan Ahmad 5d781072d1 fixed btn click in sidenav
Signed-off-by: Zishan Ahmad <zishan.barun@gmail.com>
2025-07-20 20:40:40 +05:30
Chen Su 77fee59812
Apply to be a reviewer
Signed-off-by: Chen Su <ghosind@gmail.com>
2025-07-10 13:26:38 +08:00
KubeEdge Bot 740ad0dff7
Merge pull request #56 from ghosind/main
Move web UI code into modules directory
2025-07-09 18:22:45 +08:00
Shelley Bao f61a33f9e7
Merge pull request #57 from Shelley-BaoYue/main
Add proposal directory
2025-07-09 11:22:06 +08:00
Shelley-BaoYue 7bb0b20b37 add proposal directory
Signed-off-by: Shelley-BaoYue <baoyue2@huawei.com>
2025-07-09 11:18:57 +08:00
Chen Su 17140a0fdd
Remove copyright of the gitignore file
Signed-off-by: Chen Su <ghosind@gmail.com>
2025-07-08 14:55:54 +08:00
Chen Su 21a6fe37a6
Move web UI code into modules directory
Signed-off-by: Chen Su <ghosind@gmail.com>
2025-07-03 11:22:47 +08:00
KubeEdge Bot 88becf7019
Merge pull request #49 from ghosind/fix/token-decode-error
Fix login error
2025-06-23 20:02:31 +08:00
KubeEdge Bot 9b15dded86
Merge pull request #50 from DoisLONG/main
Feature Development: Changes to the BFF  Architecture
2025-06-17 23:17:25 +08:00
DoisLONG c3160aa2a3 fix issue
Signed-off-by: DoisLONG <15221580643@163.com>
2025-06-16 09:56:35 +08:00
DoisLONG 2db5dfb834 add copyright and sort import segments
Signed-off-by: DoisLONG <15221580643@163.com>
2025-06-03 20:05:08 +08:00
DoisLONG 1bbeb09d0e fix login bug
Signed-off-by: DoisLONG <15221580643@163.com>
2025-05-28 12:01:23 +08:00
DoisLONG a739a5561e change ui pages and fix README
Signed-off-by: DoisLONG <15221580643@163.com>
2025-05-26 14:30:36 +08:00
DoisLONG 7f24e4be39 feat: update api endpoints to bff
Signed-off-by: DoisLONG <15221580643@163.com>
2025-05-20 18:43:01 +08:00
DoisLONG c0f7024b77 feat: add keink support and error handling
Signed-off-by: DoisLONG <15221580643@163.com>
2025-05-20 16:41:04 +08:00
udde 9099ac7adc Feature Development: Changes to the BFF Architecture
Signed-off-by: udde <udde@163.com>
2025-04-14 17:01:47 +08:00
KubeEdge Bot 0edfae87bb
Merge pull request #48 from DoisLONG/main
Add an example of building the image locally to the README.
2025-04-08 09:37:18 +08:00
ghosind 1055d64e04
fix: do not read token from local storage if token was set
Signed-off-by: ghosind <ghosind@gmail.com>
2025-04-07 22:25:05 +08:00
udde 5c1b9d06c4 Add an example of building the image locally to the README.
Signed-off-by: udde <udde@163.com>
2025-04-07 18:40:43 +08:00
Chen Su 20125da21d
fix: make the default username as admin to prevent token decode error
Signed-off-by: Chen Su <ghosind@gmail.com>
2025-04-07 18:12:17 +08:00
KubeEdge Bot 281f862eee
Merge pull request #40 from Faakhir30/fix_broken_links
Fix broken links in contributing doc.
2025-02-24 17:58:38 +08:00
KubeEdge Bot 3ede8b23cd
Merge pull request #34 from ghosind/fix/input-style-issue
Fix dialogs style errors
2025-02-24 17:24:37 +08:00
KubeEdge Bot 30f47f9951
Merge pull request #42 from DeshDeepakKant/fix/auto-generate-footer-year
Auto-generate footer year dynamically: replaced hardcoded year wit…
2025-02-24 16:50:37 +08:00
DeshDeepakKant df3b0fdcc3 ♻️ Auto-generate footer year dynamically: replaced hardcoded year with new Date().getFullYear()
Signed-off-by: DeshDeepakKant <deshdeepakkant@gmail.com>
2025-02-13 23:50:41 +05:30
Faakhir30 b57ad8d297 Fix broken links in contributing doc.
Signed-off-by: Faakhir30 <zahidfaakhir@gmail.com>
2025-01-24 14:10:26 +05:00
ghosind 926155fda1
fix: fixed dialogs style issues
Signed-off-by: ghosind <ghosind@gmail.com>
2024-12-24 23:07:23 +08:00
191 changed files with 6374 additions and 4602 deletions

41
.gitignore vendored
View File

@ -1,37 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
*lock.yaml
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
# IDE
.idea/
.vscode/
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# Build and dependencies
node_modules/
.next/

View File

@ -33,8 +33,8 @@ The goal of the community is to develop a cloud native edge computing platform b
# Getting started
- Fork the repository on GitHub
- Read the [setup](https://kubeedge.io/en/docs/setup/keadm/) for deployment KubeEdge cluster
- Setup Dashboard process
- Read the [setup](https://kubeedge.io/docs/setup/install-with-keadm) for deployment KubeEdge cluster
- Read the [setup](https://kubeedge.io/blog/dashboard-getting-started) for Dashboard setup
# Your First Contribution

1
OWNERS
View File

@ -6,6 +6,7 @@ approvers:
reviewers:
- fisherxu
- ghosind
- kevin-wangzefeng
- Shelley-BaoYue
- vincentgoat

View File

@ -10,50 +10,81 @@ If you have any questions, feel free to reach out to us in the following ways:
* [Slack #dashboard](https://kubeedge.io/docs/community/slack/)
## Prepare environment
nodejs, npm/yarn/pnpm is needed, pnpm is recommended
The KubeEdge dashboard consists of two modules: backend and frontend. The backend module is responsible for providing APIs to the frontend, while the frontend module is responsible for rendering the user interface.
For backend module, golang is needed.
For frontend module, nodejs, npm/yarn/pnpm is needed, pnpm is recommended.
## Install packages
### Backend
To install the backend dependencies, you need to have Go installed. You can use the following command to install the dependencies:
```bash
cd module
go mod download
```
### Frontend
To install the frontend dependencies, you can use npm, yarn, or pnpm. Choose one of the following commands based on your preference:
```bash with npm
cd module/web
npm install
```
```bash with yarn
cd module/web
yarn install
```
or
```bash with pnpm
cd module/web
pnpm install
```
### Start project
### Backend
You can start the backend server by running the following command:
```bash
cd module/api
go run main.go --apiserver-host=https://192.168.33.129:6443
```
If your API server is running with self-signed certificate, you can set `--apiserver-skip-tls-verify true` option to ignore the certificate verification.
### Frontend
```bash with npm
cd module/web
npm run build
API_SERVER={proxy address} npm run start
Example: API_SERVER=https://192.168.33.129:6443 npm run dev
API_SERVER={api module address} npm run start
Example: API_SERVER=http://127.0.0.1:8080 npm run dev
```
or
```bash with yarn
cd module/web
yarn build
API_SERVER={proxy address} yarn start
Example: API_SERVER=https://192.168.33.129:6443 yarn dev
API_SERVER={api module address} yarn start
Example: API_SERVER=http://127.0.0.1:8080 yarn dev
```
or
```bash with pnpm
cd module/web
pnpm run build
API_SERVER={proxy address} pnpm run start
Example: API_SERVER=https://192.168.33.129:6443 pnpm run dev
```
If your API server is running with self-signed certificate, you can set `NODE_TLS_REJECT_UNAUTHORIZED=0` to ignore the certificate verification.
```bash with npm
NODE_TLS_REJECT_UNAUTHORIZED=0 API_SERVER=https://192.168.33.129:6443 npm run dev
API_SERVER={api module address} pnpm run start
Example: API_SERVER=http://127.0.0.1:8080 pnpm run dev
```
### Login with token

27
docs/proposals/README.md Normal file
View File

@ -0,0 +1,27 @@
# NNNN-Title: {issue-id} - {your short, descriptive title}
- [Summary](#summary)
- [Motivation](#motivation)
- [Goals](#goals)
- [Non-Goals](#non-goals)
- [Proposal](#proposal)
- [User Stories (Optional)](#user-stories-optional)
- [Story](#story)
- [Design Details](#design-details)
## Summary
## Motivation
### Goals
### Non-Goals
## Proposal
### User Stories (Optional)
#### Story
## Design Details

60
modules/api/go.mod Normal file
View File

@ -0,0 +1,60 @@
module github.com/kubeedge/dashboard/api
go 1.23.0
require (
github.com/emicklei/go-restful/v3 v3.12.2
github.com/kubeedge/api v1.20.0
github.com/kubeedge/dashboard/errors v0.0.0-00010101000000-000000000000
github.com/kubeedge/dashboard/client v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.6
golang.org/x/tools v0.32.0
k8s.io/api v0.32.3
k8s.io/apiextensions-apiserver v0.32.3
k8s.io/apimachinery v0.32.3
k8s.io/client-go v0.32.3
k8s.io/klog/v2 v2.130.1
)
require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.7.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
replace github.com/kubeedge/dashboard/client => ../common/client
replace github.com/kubeedge/dashboard/errors => ../common/errors

162
modules/api/go.sum Normal file
View File

@ -0,0 +1,162 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubeedge/api v1.20.0 h1:JJ7SPfXAShafeU3mc881SoXY7694MymJ9J6Mq311G+U=
github.com/kubeedge/api v1.20.0/go.mod h1:4lcRzdSMStgrMioacny+xP4e0hEtFILfOlNUz8DD3z8=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

64
modules/api/main.go Normal file
View File

@ -0,0 +1,64 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"net/http"
"k8s.io/klog/v2"
"github.com/kubeedge/dashboard/api/pkg/args"
"github.com/kubeedge/dashboard/api/pkg/handler"
"github.com/kubeedge/dashboard/client"
)
func main() {
klog.InfoS("Starting KubeEdge Dashboard API")
client.Init(
client.WithAPIServer(args.APIServerHost()),
client.WithInsecure(args.APIServerSkipTLSVerify()),
client.WithKubeConfigPath(args.KubeConfigFile()),
)
apiHandler, err := handler.CreateHTTPAPIHandler()
if err != nil {
klog.ErrorS(err, "Failed to create API handler")
return
}
keinkHandler, err := handler.CreateKeinkAPIHandler()
if err != nil {
klog.ErrorS(err, "Failed to create Keink API handler")
return
}
http.Handle("/", apiHandler)
http.Handle("/keink/", keinkHandler)
serve()
select {}
}
func serve() {
addr := args.InsecureAddress()
klog.Infof("Listening and serving HTTP on %s", addr)
go func() {
klog.Fatal(http.ListenAndServe(addr, nil))
}()
}

View File

@ -0,0 +1,58 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package args
import (
"net"
"strconv"
"github.com/spf13/pflag"
)
const (
defaultInsecurePort = 8080
defaultPort = 8443
)
var (
argApiServerSkipTLSVerify = pflag.Bool("apiserver-skip-tls-verify", false, "enable if connection with remote Kubernetes API server should skip TLS verify")
argApiServerHost = pflag.String("apiserver-host", "", "address of the Kubernetes API server to connect to in the format of protocol://address:port, leave it empty if the binary runs inside cluster for local discovery attempt")
argKubeConfigFile = pflag.String("kubeconfig", "", "path to kubeconfig file with control plane location information")
argInsecurePort = pflag.Int("insecure-port", defaultInsecurePort, "port to listen to for incoming HTTP requests")
argInsecureBindAddress = pflag.IP("insecure-bind-address", net.IPv4(127, 0, 0, 1), "IP address on which to serve the --insecure-port, set to 0.0.0.0 for all interfaces")
)
func init() {
pflag.Parse()
}
func APIServerHost() string {
return *argApiServerHost
}
func APIServerSkipTLSVerify() bool {
return *argApiServerSkipTLSVerify
}
func KubeConfigFile() string {
return *argKubeConfigFile
}
func InsecureAddress() string {
return net.JoinHostPort(argInsecureBindAddress.String(), strconv.Itoa(*argInsecurePort))
}

View File

@ -0,0 +1,141 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rbacv1 "k8s.io/api/rbac/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/clusterrole"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addClusterRoleRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/clusterrole").To(apiHandler.handleGetClusterRoles).
Writes(rbacv1.ClusterRoleList{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRoleList{}))
apiV1Ws.Route(
apiV1Ws.GET("/clusterrole/{name}").To(apiHandler.handleGetClusterRole).
Param(apiV1Ws.PathParameter("name", "Name of the ClusterRole")).
Writes(rbacv1.ClusterRole{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRole{}))
apiV1Ws.Route(
apiV1Ws.POST("/clusterrole").To(apiHandler.handleCreateClusterRole).
Reads(rbacv1.ClusterRole{}).
Writes(rbacv1.ClusterRole{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRole{}))
apiV1Ws.Route(
apiV1Ws.PUT("/clusterrole").To(apiHandler.handleUpdateClusterRole).
Reads(rbacv1.ClusterRole{}).
Writes(rbacv1.ClusterRole{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRole{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/clusterrole/{name}").To(apiHandler.handleDeleteClusterRole).
Param(apiV1Ws.PathParameter("name", "Name of the ClusterRole")).
Returns(http.StatusNoContent, "OK", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetClusterRoles(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
result, err := clusterrole.GetClusterRoleList(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetClusterRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
result, err := clusterrole.GetClusterRole(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleCreateClusterRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
clusterRole := new(rbacv1.ClusterRole)
err = request.ReadEntity(&clusterRole)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := clusterrole.CreateClusterRole(k8sClient, clusterRole)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleUpdateClusterRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
clusterRole := new(rbacv1.ClusterRole)
err = request.ReadEntity(&clusterRole)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := clusterrole.UpdateClusterRole(k8sClient, clusterRole)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteClusterRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
err = clusterrole.DeleteClusterRole(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,141 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rbacv1 "k8s.io/api/rbac/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/clusterrolebinding"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addClusterRoleBindingRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/clusterrolebinding").To(apiHandler.handleGetClusterRoleBindings).
Writes(rbacv1.ClusterRoleBindingList{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRoleBindingList{}))
apiV1Ws.Route(
apiV1Ws.GET("/clusterrolebinding/{name}").To(apiHandler.handleGetClusterRoleBinding).
Param(apiV1Ws.PathParameter("name", "Name of the ClusterRoleBinding")).
Writes(rbacv1.ClusterRoleBinding{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRoleBinding{}))
apiV1Ws.Route(
apiV1Ws.POST("/clusterrolebinding").To(apiHandler.handleCreateClusterRoleBinding).
Reads(rbacv1.ClusterRoleBinding{}).
Writes(rbacv1.ClusterRoleBinding{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRoleBinding{}))
apiV1Ws.Route(
apiV1Ws.PUT("/clusterrolebinding").To(apiHandler.handleUpdateClusterRoleBinding).
Reads(rbacv1.ClusterRoleBinding{}).
Writes(rbacv1.ClusterRoleBinding{}).
Returns(http.StatusOK, "OK", rbacv1.ClusterRoleBinding{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/clusterrolebinding/{name}").To(apiHandler.handleDeleteClusterRoleBinding).
Param(apiV1Ws.PathParameter("name", "Name of the ClusterRoleBinding")).
Returns(http.StatusNoContent, "OK", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetClusterRoleBindings(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
result, err := clusterrolebinding.GetClusterRoleBindingList(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetClusterRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
result, err := clusterrolebinding.GetClusterRoleBinding(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleCreateClusterRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
clusterRoleBinding := new(rbacv1.ClusterRoleBinding)
err = request.ReadEntity(&clusterRoleBinding)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := clusterrolebinding.CreateClusterRoleBinding(k8sClient, clusterRoleBinding)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleUpdateClusterRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
clusterRoleBinding := new(rbacv1.ClusterRoleBinding)
err = request.ReadEntity(&clusterRoleBinding)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := clusterrolebinding.UpdateClusterRoleBinding(k8sClient, clusterRoleBinding)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteClusterRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
err = clusterrolebinding.DeleteClusterRoleBinding(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,51 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
"k8s.io/apimachinery/pkg/version"
"github.com/kubeedge/dashboard/api/pkg/resource/common"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addCommonRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/version").To(apiHandler.getVersion).
Writes(version.Info{}).
Returns(http.StatusOK, "OK", version.Info{}))
return apiHandler
}
func (apiHandler *APIHandler) getVersion(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
versionInfo, err := common.GetVersion(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(versionInfo)
}

View File

@ -0,0 +1,155 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/configmap"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addConfigMapRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/configmap").To(apiHandler.handleGetConfigMaps).
Writes(corev1.ConfigMapList{}).
Returns(http.StatusOK, "OK", corev1.ConfigMapList{}))
apiV1Ws.Route(
apiV1Ws.GET("/configmap/{namespace}").To(apiHandler.handleGetConfigMaps).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the ConfigMap")).
Writes(corev1.ConfigMapList{}).
Returns(http.StatusOK, "OK", corev1.ConfigMapList{}))
apiV1Ws.Route(
apiV1Ws.GET("/configmap/{namespace}/{name}").To(apiHandler.handleGetConfigMap).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the ConfigMap")).
Param(apiV1Ws.PathParameter("name", "Name of the ConfigMap")).
Writes(corev1.ConfigMap{}).
Returns(http.StatusOK, "OK", corev1.ConfigMap{}))
apiV1Ws.Route(
apiV1Ws.POST("/configmap/{namespace}").To(apiHandler.handleCreateConfigMap).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the ConfigMap")).
Reads(corev1.ConfigMap{}).
Writes(corev1.ConfigMap{}).
Returns(http.StatusCreated, "Created", corev1.ConfigMap{}))
apiV1Ws.Route(
apiV1Ws.PUT("/configmap/{namespace}").To(apiHandler.handleUpdateConfigMap).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the ConfigMap")).
Reads(corev1.ConfigMap{}).
Writes(corev1.ConfigMap{}).
Returns(http.StatusOK, "OK", corev1.ConfigMap{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/configmap/{namespace}/{name}").To(apiHandler.handleDeleteConfigMap).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the ConfigMap")).
Param(apiV1Ws.PathParameter("name", "Name of the ConfigMap")).
Writes(corev1.ConfigMap{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetConfigMaps(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
result, err := configmap.GetConfigMapList(k8sClient, request.PathParameter("namespace"))
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetConfigMap(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := configmap.GetConfigMap(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleCreateConfigMap(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
configMap := new(corev1.ConfigMap)
if err := request.ReadEntity(configMap); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := configmap.CreateConfigMap(k8sClient, namespace, configMap)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleUpdateConfigMap(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
configMap := new(corev1.ConfigMap)
if err := request.ReadEntity(configMap); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := configmap.UpdateConfigMap(k8sClient, namespace, configMap)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteConfigMap(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = configmap.DeleteConfigMap(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/crd"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addCRDRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/crd").To(apiHandler.getCRDs).
Writes(apiextensionsv1.CustomResourceDefinitionList{}).
Returns(http.StatusOK, "OK", apiextensionsv1.CustomResourceDefinitionList{}))
apiV1Ws.Route(
apiV1Ws.GET("/crd/{name}").To(apiHandler.getCRD).
Param(apiV1Ws.PathParameter("name", "Name of the CRD")).
Writes(apiextensionsv1.CustomResourceDefinition{}).
Returns(http.StatusOK, "OK", apiextensionsv1.CustomResourceDefinition{}))
return apiHandler
}
func (apiHandler *APIHandler) getCRDs(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getAPIExtensionClient(request, response)
if err != nil {
return
}
result, err := crd.GetCRDList(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) getCRD(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getAPIExtensionClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
result, err := crd.GetCRD(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}

View File

@ -0,0 +1,155 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
appsv1 "k8s.io/api/apps/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/deployment"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addDeploymentRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/deployment").To(apiHandler.handleGetDeployments).
Writes(appsv1.DeploymentList{}).
Returns(http.StatusOK, "OK", appsv1.DeploymentList{}))
apiV1Ws.Route(
apiV1Ws.GET("/deployment/{namespace}").To(apiHandler.handleGetDeployments).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the deployment")).
Writes(appsv1.DeploymentList{}).
Returns(http.StatusOK, "OK", appsv1.DeploymentList{}))
apiV1Ws.Route(
apiV1Ws.GET("/deployment/{namespace}/{name}").To(apiHandler.handleGetDeployment).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the deployment")).
Param(apiV1Ws.PathParameter("name", "Name of the deployment")).
Writes(appsv1.Deployment{}).
Returns(http.StatusOK, "OK", appsv1.Deployment{}))
apiV1Ws.Route(
apiV1Ws.POST("/deployment/{namespace}").To(apiHandler.handleCreateDeployment).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the deployment")).
Reads(appsv1.Deployment{}).
Writes(appsv1.Deployment{}).
Returns(http.StatusCreated, "Created", appsv1.Deployment{}))
apiV1Ws.Route(
apiV1Ws.PUT("/deployment/{namespace}").To(apiHandler.handleUpdateDeployment).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the deployment")).
Reads(appsv1.Deployment{}).
Writes(appsv1.Deployment{}).
Returns(http.StatusOK, "OK", appsv1.Deployment{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/deployment/{namespace}/{name}").To(apiHandler.handleDeleteDeployment).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the deployment")).
Param(apiV1Ws.PathParameter("name", "Name of the deployment")).
Writes(appsv1.Deployment{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetDeployments(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := deployment.GetDeploymentList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetDeployment(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := deployment.GetDeployment(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleCreateDeployment(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(appsv1.Deployment)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := deployment.CreateDeployment(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleUpdateDeployment(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(appsv1.Deployment)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := deployment.UpdateDeployment(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteDeployment(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = deployment.DeleteDeployment(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,152 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
devicev1beta1 "github.com/kubeedge/api/apis/devices/v1beta1"
"github.com/kubeedge/dashboard/api/pkg/resource/device"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addDeviceRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/device").To(apiHandler.handleGetDevices).
Writes(devicev1beta1.DeviceList{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/device/{namespace}").To(apiHandler.handleGetDevices).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device")).
Writes(devicev1beta1.DeviceList{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/device/{namespace}/{name}").To(apiHandler.handleGetDevice).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device")).
Param(apiV1Ws.PathParameter("name", "Name of the device")).
Writes(devicev1beta1.Device{}).
Returns(http.StatusOK, "OK", devicev1beta1.Device{}))
apiV1Ws.Route(
apiV1Ws.POST("/device/{namespace}").To(apiHandler.handleCreateDevice).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device")).
Reads(devicev1beta1.Device{}).
Writes(devicev1beta1.Device{}).
Returns(http.StatusCreated, "Created", devicev1beta1.Device{}))
apiV1Ws.Route(
apiV1Ws.PUT("/device/{namespace}").To(apiHandler.handleUpdateDevice).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device")).
Reads(devicev1beta1.Device{}).
Writes(devicev1beta1.Device{}).
Returns(http.StatusOK, "OK", devicev1beta1.Device{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/device/{namespace}/{name}").To(apiHandler.handleDeleteDevice).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device")).
Param(apiV1Ws.PathParameter("name", "Name of the device")).
Writes(devicev1beta1.Device{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetDevices(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := device.GetDeviceList(kubeedgeClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetDevice(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := device.GetDevice(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateDevice(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(devicev1beta1.Device)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := device.CreateDevice(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateDevice(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(devicev1beta1.Device)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := device.UpdateDevice(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteDevice(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = device.DeleteDevice(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,161 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
devicev1beta1 "github.com/kubeedge/api/apis/devices/v1beta1"
"github.com/kubeedge/dashboard/api/pkg/resource/devicemodel"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addDeviceModelRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/devicemodel").To(apiHandler.handleGetDeviceModels).
Writes(devicev1beta1.DeviceModelList{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceModelList{}))
apiV1Ws.Route(
apiV1Ws.GET("/devicemodel/{namespace}").To(apiHandler.handleGetDeviceModels).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device model")).
Writes(devicev1beta1.DeviceModelList{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceModelList{}))
apiV1Ws.Route(
apiV1Ws.GET("/devicemodel/{namespace}/{name}").To(apiHandler.handleGetDeviceModel).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device model")).
Param(apiV1Ws.PathParameter("name", "Name of the device model")).
Writes(devicev1beta1.DeviceModel{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceModel{}))
apiV1Ws.Route(
apiV1Ws.POST("/devicemodel/{namespace}").To(apiHandler.handleCreateDeviceModel).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device model")).
Reads(devicev1beta1.DeviceModel{}).
Writes(devicev1beta1.DeviceModel{}).
Returns(http.StatusCreated, "Created", devicev1beta1.DeviceModel{}))
apiV1Ws.Route(
apiV1Ws.PUT("/devicemodel/{namespace}").To(apiHandler.handleUpdateDeviceModel).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device model")).
Reads(devicev1beta1.DeviceModel{}).
Writes(devicev1beta1.DeviceModel{}).
Returns(http.StatusOK, "OK", devicev1beta1.DeviceModel{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/devicemodel/{namespace}/{name}").To(apiHandler.handleDeleteDeviceModel).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the device model")).
Param(apiV1Ws.PathParameter("name", "Name of the device model")).
Writes(devicev1beta1.DeviceModel{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetDeviceModels(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := devicemodel.GetDeviceModelList(kubeedgeClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetDeviceModel(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := devicemodel.GetDeviceModel(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateDeviceModel(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
deviceModel := &devicev1beta1.DeviceModel{}
err = request.ReadEntity(deviceModel)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := devicemodel.CreateDeviceModel(kubeedgeClient, namespace, deviceModel)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateDeviceModel(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
deviceModel := &devicev1beta1.DeviceModel{}
err = request.ReadEntity(deviceModel)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := devicemodel.UpdateDeviceModel(kubeedgeClient, namespace, deviceModel)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteDeviceModel(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = devicemodel.DeleteDeviceModel(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,159 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
appsv1alpha1 "github.com/kubeedge/api/apis/apps/v1alpha1"
"github.com/kubeedge/dashboard/api/pkg/resource/edgeapplication"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addEdgeApplicationRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/edgeapplication").To(apiHandler.handleGetEdgeApplications).
Writes(appsv1alpha1.EdgeApplicationList{}).
Returns(http.StatusOK, "OK", appsv1alpha1.EdgeApplicationList{}))
apiV1Ws.Route(
apiV1Ws.GET("/edgeapplication/{namespace}").To(apiHandler.handleGetEdgeApplications).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the edge application")).
Writes(appsv1alpha1.EdgeApplicationList{}).
Returns(http.StatusOK, "OK", appsv1alpha1.EdgeApplicationList{}))
apiV1Ws.Route(
apiV1Ws.GET("/edgeapplication/{namespace}/{name}").To(apiHandler.handleGetEdgeApplication).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the edge application")).
Param(apiV1Ws.PathParameter("name", "Name of the edge application")).
Writes(appsv1alpha1.EdgeApplication{}).
Returns(http.StatusOK, "OK", appsv1alpha1.EdgeApplication{}))
apiV1Ws.Route(
apiV1Ws.POST("/edgeapplication/{namespace}").To(apiHandler.handleCreateEdgeApplication).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the edge application")).
Reads(appsv1alpha1.EdgeApplication{}).
Writes(appsv1alpha1.EdgeApplication{}).
Returns(http.StatusCreated, "Created", appsv1alpha1.EdgeApplication{}))
apiV1Ws.Route(
apiV1Ws.PUT("/edgeapplication/{namespace}").To(apiHandler.handleUpdateEdgeApplication).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the edge application")).
Reads(appsv1alpha1.EdgeApplication{}).
Writes(appsv1alpha1.EdgeApplication{}).
Returns(http.StatusOK, "OK", appsv1alpha1.EdgeApplication{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/edgeapplication/{namespace}/{name}").To(apiHandler.handleDeleteEdgeApplication).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the edge application")).
Param(apiV1Ws.PathParameter("name", "Name of the edge application")).
Writes(appsv1alpha1.EdgeApplication{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetEdgeApplications(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := edgeapplication.GetEdgeApplicationList(kubeedgeClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetEdgeApplication(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := edgeapplication.GetEdgeApplication(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateEdgeApplication(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(appsv1alpha1.EdgeApplication)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := edgeapplication.CreateEdgeApplication(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateEdgeApplication(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(appsv1alpha1.EdgeApplication)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := edgeapplication.UpdateEdgeApplication(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteEdgeApplication(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = edgeapplication.DeleteEdgeApplication(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,70 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"fmt"
"github.com/emicklei/go-restful/v3"
"k8s.io/klog/v2"
"github.com/kubeedge/dashboard/api/pkg/kubeedge"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) runKubeEdgeByKeink(request *restful.Request, response *restful.Response) {
klog.Info("run kubeedge by keink")
outputCh, errCh, err := kubeedge.RunKubeEdgeByKeink()
if err != nil {
errors.HandleInternalError(response, err)
return
}
// Set SSE headers
response.Header().Set("Access-Control-Allow-Origin", "*")
response.Header().Set("Access-Control-Allow-Headers", "Content-Type")
response.Header().Set("Content-Type", "text/event-stream")
response.Header().Set("Cache-Control", "no-cache")
writer := response.ResponseWriter
for {
select {
case output := <-outputCh:
if output != "" {
fmt.Fprintf(writer, "data: %s\n\n", output)
response.Flush()
}
case err := <-errCh:
if err != nil {
writer.Write([]byte("event error\ndata: " + err.Error() + " \n\n"))
} else {
writer.Write([]byte("data: KubeEdge installation completed successfully\n\n"))
}
writer.Write([]byte("event: done\ndata: \n\n"))
response.Flush()
return
}
}
}
func (apiHandler *APIHandler) checkIsAbleToRunKeink(request *restful.Request, response *restful.Response) {
ok := kubeedge.CheckIsAbleToRunKeink()
response.WriteAsJson(map[string]bool{"ok": ok})
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/namespace"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addNamespaceRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/namespace").To(apiHandler.handleGetNamespaces).
Writes(corev1.NamespaceList{}).
Returns(http.StatusOK, "OK", corev1.NamespaceList{}))
return apiHandler
}
func (apiHandler *APIHandler) handleGetNamespaces(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
result, err := namespace.GetNamespaceList(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}

View File

@ -0,0 +1,116 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/node"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addNodeRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/node").To(apiHandler.handleGetNodes).
Writes(corev1.NamespaceList{}).
Returns(http.StatusOK, "OK", corev1.NamespaceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/node/{name}").To(apiHandler.handleGetNode).
Param(apiV1Ws.PathParameter("name", "Name of the node")).
Writes(corev1.Node{}).
Returns(http.StatusOK, "OK", corev1.Node{}))
apiV1Ws.Route(
apiV1Ws.PUT("/node").To(apiHandler.handleUpdateNode).
Reads(corev1.Node{}).
Writes(corev1.Node{}).
Returns(http.StatusOK, "OK", corev1.Node{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/node/{name}").To(apiHandler.handleDeleteNode).
Param(apiV1Ws.PathParameter("name", "Name of the node")).
Writes(corev1.Node{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetNodes(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
result, err := node.GetNodeList(k8sClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetNode(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
result, err := node.GetNode(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleUpdateNode(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
data := new(corev1.Node)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := node.UpdateNode(k8sClient, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteNode(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
err = node.DeleteNode(k8sClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,145 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
appsv1alpha1 "github.com/kubeedge/api/apis/apps/v1alpha1"
"github.com/kubeedge/dashboard/api/pkg/resource/nodegroup"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addNodeGroupRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/nodegroup").To(apiHandler.handleGetNodeGroups).
Writes(appsv1alpha1.NodeGroupList{}).
Returns(http.StatusOK, "OK", appsv1alpha1.NodeGroupList{}))
apiV1Ws.Route(
apiV1Ws.GET("/nodegroup/{name}").To(apiHandler.handleGetNodeGroup).
Param(apiV1Ws.PathParameter("name", "Name of the node group")).
Writes(appsv1alpha1.NodeGroup{}).
Returns(http.StatusOK, "OK", appsv1alpha1.NodeGroup{}))
apiV1Ws.Route(
apiV1Ws.POST("/nodegroup").To(apiHandler.handleCreateNodeGroup).
Reads(appsv1alpha1.NodeGroup{}).
Writes(appsv1alpha1.NodeGroup{}).
Returns(http.StatusCreated, "Created", appsv1alpha1.NodeGroup{}))
apiV1Ws.Route(
apiV1Ws.PUT("/nodegroup").To(apiHandler.handleUpdateNodeGroup).
Reads(appsv1alpha1.NodeGroup{}).
Writes(appsv1alpha1.NodeGroup{}).
Returns(http.StatusOK, "OK", appsv1alpha1.NodeGroup{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/nodegroup/{name}").To(apiHandler.handleDeleteNodeGroup).
Param(apiV1Ws.PathParameter("name", "Name of the node group")).
Writes(appsv1alpha1.NodeGroup{}).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetNodeGroups(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
result, err := nodegroup.GetNodeGroupList(kubeedgeClient)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetNodeGroup(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
result, err := nodegroup.GetNodeGroup(kubeedgeClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateNodeGroup(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
data := new(appsv1alpha1.NodeGroup)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := nodegroup.CreateNodeGroup(kubeedgeClient, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateNodeGroup(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
data := new(appsv1alpha1.NodeGroup)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := nodegroup.UpdateNodeGroup(kubeedgeClient, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteNodeGroup(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
name := request.PathParameter("name")
err = nodegroup.DeleteNodeGroup(kubeedgeClient, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,56 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/pod"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addPodRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/pod").To(apiHandler.handleGetPods).
Writes(corev1.PodList{}).
Returns(http.StatusOK, "OK", corev1.PodList{}))
apiV1Ws.Route(
apiV1Ws.GET("/pod/{namespace}").To(apiHandler.handleGetPods).
Param(apiV1Ws.PathParameter("namespace", "Namespace of the Pod")).
Writes(corev1.PodList{}).
Returns(http.StatusOK, "OK", corev1.PodList{}))
return apiHandler
}
func (apiHandler *APIHandler) handleGetPods(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := pod.GetPodList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}

View File

@ -0,0 +1,151 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rbacv1 "k8s.io/api/rbac/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/role"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addRoleRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/role").To(apiHandler.handleGetRoles).
Writes(rbacv1.RoleList{}).
Returns(http.StatusOK, "OK", rbacv1.RoleList{}))
apiV1Ws.Route(
apiV1Ws.GET("/role/{namespace}").To(apiHandler.handleGetRoles).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(rbacv1.RoleList{}).
Returns(http.StatusOK, "OK", rbacv1.RoleList{}))
apiV1Ws.Route(
apiV1Ws.GET("/role/{namespace}/{name}").To(apiHandler.handleGetRole).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the role")).
Writes(rbacv1.Role{}).
Returns(http.StatusOK, "OK", rbacv1.Role{}))
apiV1Ws.Route(
apiV1Ws.POST("/role/{namespace}").To(apiHandler.handleCreateRole).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rbacv1.Role{}).
Writes(rbacv1.Role{}).
Returns(http.StatusCreated, "Created", rbacv1.Role{}))
apiV1Ws.Route(
apiV1Ws.PUT("/role/{namespace}").To(apiHandler.handleUpdateRole).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rbacv1.Role{}).
Writes(rbacv1.Role{}).
Returns(http.StatusOK, "OK", rbacv1.Role{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/role/{namespace}/{name}").To(apiHandler.handleDeleteRole).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the role")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetRoles(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := role.GetRoleList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleGetRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := role.GetRole(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleCreateRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rbacv1.Role)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := role.CreateRole(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) handleUpdateRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rbacv1.Role)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := role.UpdateRole(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) handleDeleteRole(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = role.DeleteRole(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,160 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rbacv1 "k8s.io/api/rbac/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/rolebinding"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addRoleBindingRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/rolebinding").To(apiHandler.handleGetRoleBindings).
Writes(rbacv1.RoleBindingList{}).
Returns(http.StatusOK, "OK", rbacv1.RoleBindingList{}))
apiV1Ws.Route(
apiV1Ws.GET("/rolebinding/{namespace}").To(apiHandler.handleGetRoleBindings).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(rbacv1.RoleBindingList{}).
Returns(http.StatusOK, "OK", rbacv1.RoleBindingList{}))
apiV1Ws.Route(
apiV1Ws.GET("/rolebinding/{namespace}/{name}").To(apiHandler.handleGetRoleBinding).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the role binding")).
Writes(rbacv1.RoleBinding{}).
Returns(http.StatusOK, "OK", rbacv1.RoleBinding{}))
apiV1Ws.Route(
apiV1Ws.POST("/rolebinding/{namespace}").To(apiHandler.handleCreateRoleBinding).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rbacv1.RoleBinding{}).
Writes(rbacv1.RoleBinding{}).
Returns(http.StatusCreated, "Created", rbacv1.RoleBinding{}))
apiV1Ws.Route(
apiV1Ws.PUT("/rolebinding/{namespace}").To(apiHandler.handleUpdateRoleBinding).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rbacv1.RoleBinding{}).
Writes(rbacv1.RoleBinding{}).
Returns(http.StatusOK, "OK", rbacv1.RoleBinding{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/rolebinding/{namespace}/{name}").To(apiHandler.handleDeleteRoleBinding).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the role binding")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetRoleBindings(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := rolebinding.GetRoleBindingList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := rolebinding.GetRoleBinding(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rbacv1.RoleBinding)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := rolebinding.CreateRoleBinding(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rbacv1.RoleBinding)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := rolebinding.UpdateRoleBinding(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteRoleBinding(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = rolebinding.DeleteRoleBinding(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,80 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"github.com/emicklei/go-restful/v3"
)
type APIHandler struct {
}
func CreateHTTPAPIHandler() (*restful.Container, error) {
apiHandler := APIHandler{}
wsContainer := restful.NewContainer()
wsContainer.EnableContentEncoding(true)
apiV1Ws := new(restful.WebService)
apiV1Ws.Path("/api/v1").Produces(restful.MIME_JSON).Consumes(restful.MIME_JSON)
apiHandler.
addClusterRoleRoutes(apiV1Ws).
addClusterRoleBindingRoutes(apiV1Ws).
addConfigMapRoutes(apiV1Ws).
addCRDRoutes(apiV1Ws).
addDeploymentRoutes(apiV1Ws).
addDeviceRoutes(apiV1Ws).
addDeviceModelRoutes(apiV1Ws).
addEdgeApplicationRoutes(apiV1Ws).
addNamespaceRoutes(apiV1Ws).
addNodeRoutes(apiV1Ws).
addNodeGroupRoutes(apiV1Ws).
addPodRoutes(apiV1Ws).
addRoleRoutes(apiV1Ws).
addRoleBindingRoutes(apiV1Ws).
addRuleRoutes(apiV1Ws).
addRuleEndpointRoutes(apiV1Ws).
addSecretRoutes(apiV1Ws).
addServiceRoutes(apiV1Ws).
addServiceAccountRoutes(apiV1Ws).
addCommonRoutes(apiV1Ws)
wsContainer.Add(apiV1Ws)
return wsContainer, nil
}
func CreateKeinkAPIHandler() (*restful.Container, error) {
apiHandler := APIHandler{}
wsContainer := restful.NewContainer()
keinkWs := new(restful.WebService)
keinkWs.Route(
keinkWs.GET("/keink/run").
To(apiHandler.runKubeEdgeByKeink).Produces("text/event-stream"))
keinkWs.Route(
keinkWs.GET("/keink/check").
To(apiHandler.checkIsAbleToRunKeink).Produces(restful.MIME_JSON).Returns(200, "OK", nil))
wsContainer.Add(keinkWs)
return wsContainer, nil
}

View File

@ -0,0 +1,160 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rulev1 "github.com/kubeedge/api/apis/rules/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/rule"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addRuleRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/rule").To(apiHandler.handleGetRules).
Writes(rulev1.RuleList{}).
Returns(http.StatusOK, "OK", rulev1.RuleList{}))
apiV1Ws.Route(
apiV1Ws.GET("/rule/{namespace}").To(apiHandler.handleGetRules).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(rulev1.RuleList{}).
Returns(http.StatusOK, "OK", rulev1.RuleList{}))
apiV1Ws.Route(
apiV1Ws.GET("/rule/{namespace}/{name}").To(apiHandler.handleGetRule).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the rule")).
Writes(rulev1.Rule{}).
Returns(http.StatusOK, "OK", rulev1.Rule{}))
apiV1Ws.Route(
apiV1Ws.POST("/rule/{namespace}").To(apiHandler.handleCreateRule).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rulev1.Rule{}).
Writes(rulev1.Rule{}).
Returns(http.StatusCreated, "Created", rulev1.Rule{}))
apiV1Ws.Route(
apiV1Ws.PUT("/rule/{namespace}").To(apiHandler.handleUpdateRule).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rulev1.Rule{}).
Writes(rulev1.Rule{}).
Returns(http.StatusOK, "OK", rulev1.Rule{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/rule/{namespace}/{name}").To(apiHandler.handleDeleteRule).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the rule")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetRules(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := rule.GetRuleList(kubeedgeClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetRule(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := rule.GetRule(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateRule(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rulev1.Rule)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := rule.CreateRule(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateRule(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rulev1.Rule)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := rule.UpdateRule(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteRule(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = rule.DeleteRule(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,160 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
rulev1 "github.com/kubeedge/api/apis/rules/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/ruleendpoint"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addRuleEndpointRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/ruleendpoint").To(apiHandler.handleGetRuleEndpoints).
Writes(rulev1.RuleEndpointList{}).
Returns(http.StatusOK, "OK", rulev1.RuleEndpointList{}))
apiV1Ws.Route(
apiV1Ws.GET("/ruleendpoint/{namespace}").To(apiHandler.handleGetRuleEndpoints).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(rulev1.RuleEndpointList{}).
Returns(http.StatusOK, "OK", rulev1.RuleEndpointList{}))
apiV1Ws.Route(
apiV1Ws.GET("/ruleendpoint/{namespace}/{name}").To(apiHandler.handleGetRuleEndpoint).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the rule endpoint")).
Writes(rulev1.RuleEndpoint{}).
Returns(http.StatusOK, "OK", rulev1.RuleEndpoint{}))
apiV1Ws.Route(
apiV1Ws.POST("/ruleendpoint/{namespace}").To(apiHandler.handleCreateRuleEndpoint).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rulev1.RuleEndpoint{}).
Writes(rulev1.RuleEndpoint{}).
Returns(http.StatusCreated, "Created", rulev1.RuleEndpoint{}))
apiV1Ws.Route(
apiV1Ws.PUT("/ruleendpoint/{namespace}").To(apiHandler.handleUpdateRuleEndpoint).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(rulev1.RuleEndpoint{}).
Writes(rulev1.RuleEndpoint{}).
Returns(http.StatusOK, "OK", rulev1.RuleEndpoint{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/ruleendpoint/{namespace}/{name}").To(apiHandler.handleDeleteRuleEndpoint).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the rule endpoint")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetRuleEndpoints(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := ruleendpoint.GetRuleEndpointList(kubeedgeClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetRuleEndpoint(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := ruleendpoint.GetRuleEndpoint(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateRuleEndpoint(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rulev1.RuleEndpoint)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := ruleendpoint.CreateRuleEndpoint(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateRuleEndpoint(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(rulev1.RuleEndpoint)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := ruleendpoint.UpdateRuleEndpoint(kubeedgeClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteRuleEndpoint(request *restful.Request, response *restful.Response) {
kubeedgeClient, err := apiHandler.getKubeEdgeClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = ruleendpoint.DeleteRuleEndpoint(kubeedgeClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,160 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/secret"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addSecretRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/secret").To(apiHandler.handleGetSecrets).
Writes(corev1.SecretList{}).
Returns(http.StatusOK, "OK", corev1.SecretList{}))
apiV1Ws.Route(
apiV1Ws.GET("/secret/{namespace}").To(apiHandler.handleGetSecrets).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(corev1.SecretList{}).
Returns(http.StatusOK, "OK", corev1.SecretList{}))
apiV1Ws.Route(
apiV1Ws.GET("/secret/{namespace}/{name}").To(apiHandler.handleGetSecret).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the secret")).
Writes(corev1.Secret{}).
Returns(http.StatusOK, "OK", corev1.Secret{}))
apiV1Ws.Route(
apiV1Ws.POST("/secret/{namespace}").To(apiHandler.handleCreateSecret).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.Secret{}).
Writes(corev1.Secret{}).
Returns(http.StatusCreated, "Created", corev1.Secret{}))
apiV1Ws.Route(
apiV1Ws.PUT("/secret/{namespace}").To(apiHandler.handleUpdateSecret).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.Secret{}).
Writes(corev1.Secret{}).
Returns(http.StatusOK, "OK", corev1.Secret{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/secret/{namespace}/{name}").To(apiHandler.handleDeleteSecret).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the secret")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) handleGetSecrets(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := secret.GetSecretList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleGetSecret(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := secret.GetSecret(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleCreateSecret(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
data := new(corev1.Secret)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
namespace := request.PathParameter("namespace")
result, err := secret.CreateSecret(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleUpdateSecret(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
data := new(corev1.Secret)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
namespace := request.PathParameter("namespace")
result, err := secret.UpdateSecret(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) handleDeleteSecret(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = secret.DeleteSecret(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,155 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/service"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addServiceRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/service").To(apiHandler.getServiceList).
Writes(corev1.ServiceList{}).
Returns(http.StatusOK, "OK", corev1.ServiceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/service/{namespace}").To(apiHandler.getServiceList).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(corev1.ServiceList{}).
Returns(http.StatusOK, "OK", corev1.ServiceList{}))
apiV1Ws.Route(
apiV1Ws.GET("/service/{namespace}/{name}").To(apiHandler.getService).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the service")).
Writes(corev1.Service{}).
Returns(http.StatusOK, "OK", corev1.Service{}))
apiV1Ws.Route(
apiV1Ws.POST("/service/{namespace}").To(apiHandler.createService).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.Service{}).
Writes(corev1.Service{}).
Returns(http.StatusCreated, "Created", corev1.Service{}))
apiV1Ws.Route(
apiV1Ws.PUT("/service/{namespace}").To(apiHandler.updateService).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.Service{}).
Writes(corev1.Service{}).
Returns(http.StatusOK, "OK", corev1.Service{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/service/{namespace}/{name}").To(apiHandler.deleteService).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the service")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) getServiceList(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := service.GetServiceList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) getService(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := service.GetService(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) createService(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(corev1.Service)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := service.CreateService(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusCreated, result)
}
func (apiHandler *APIHandler) updateService(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(corev1.Service)
err = request.ReadEntity(data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := service.UpdateService(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeaderAndEntity(http.StatusOK, result)
}
func (apiHandler *APIHandler) deleteService(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = service.DeleteService(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,158 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"net/http"
"github.com/emicklei/go-restful/v3"
corev1 "k8s.io/api/core/v1"
"github.com/kubeedge/dashboard/api/pkg/resource/serviceaccount"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) addServiceAccountRoutes(apiV1Ws *restful.WebService) *APIHandler {
apiV1Ws.Route(
apiV1Ws.GET("/serviceaccount").To(apiHandler.getServiceAccountList).
Writes(corev1.ServiceAccountList{}).
Returns(http.StatusOK, "OK", corev1.ServiceAccountList{}))
apiV1Ws.Route(
apiV1Ws.GET("/serviceaccount/{namespace}").To(apiHandler.getServiceAccountList).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Writes(corev1.ServiceAccountList{}).
Returns(http.StatusOK, "OK", corev1.ServiceAccountList{}))
apiV1Ws.Route(
apiV1Ws.GET("/serviceaccount/{namespace}/{name}").To(apiHandler.getServiceAccount).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the service account")).
Writes(corev1.ServiceAccount{}).
Returns(http.StatusOK, "OK", corev1.ServiceAccount{}))
apiV1Ws.Route(
apiV1Ws.POST("/serviceaccount/{namespace}").To(apiHandler.createServiceAccount).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.ServiceAccount{}).
Writes(corev1.ServiceAccount{}).
Returns(http.StatusCreated, "Created", corev1.ServiceAccount{}))
apiV1Ws.Route(
apiV1Ws.PUT("/serviceaccount/{namespace}").To(apiHandler.updateServiceAccount).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Reads(corev1.ServiceAccount{}).
Writes(corev1.ServiceAccount{}).
Returns(http.StatusOK, "OK", corev1.ServiceAccount{}))
apiV1Ws.Route(
apiV1Ws.DELETE("/serviceaccount/{namespace}/{name}").To(apiHandler.deleteServiceAccount).
Param(apiV1Ws.PathParameter("namespace", "Name of the namespace")).
Param(apiV1Ws.PathParameter("name", "Name of the service account")).
Returns(http.StatusNoContent, "No Content", nil))
return apiHandler
}
func (apiHandler *APIHandler) getServiceAccountList(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
result, err := serviceaccount.GetServiceAccountList(k8sClient, namespace)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) getServiceAccount(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
result, err := serviceaccount.GetServiceAccount(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) createServiceAccount(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(corev1.ServiceAccount)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := serviceaccount.CreateServiceAccount(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) updateServiceAccount(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
data := new(corev1.ServiceAccount)
if err := request.ReadEntity(data); err != nil {
errors.HandleInternalError(response, err)
return
}
result, err := serviceaccount.UpdateServiceAccount(k8sClient, namespace, data)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteEntity(result)
}
func (apiHandler *APIHandler) deleteServiceAccount(request *restful.Request, response *restful.Response) {
k8sClient, err := apiHandler.getK8sClient(request, response)
if err != nil {
return
}
namespace := request.PathParameter("namespace")
name := request.PathParameter("name")
err = serviceaccount.DeleteServiceAccount(k8sClient, namespace, name)
if err != nil {
errors.HandleInternalError(response, err)
return
}
response.WriteHeader(http.StatusNoContent)
}

View File

@ -0,0 +1,66 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package handler
import (
"github.com/emicklei/go-restful/v3"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
k8sClient "k8s.io/client-go/kubernetes"
"github.com/kubeedge/dashboard/client"
"github.com/kubeedge/dashboard/errors"
)
func (apiHandler *APIHandler) getK8sClient(
request *restful.Request,
response *restful.Response,
) (k8sClient.Interface, error) {
k8sClient, err := client.Client(request.Request)
if err != nil {
errors.HandleInternalError(response, err)
return nil, err
}
return k8sClient, nil
}
func (apiHandler *APIHandler) getAPIExtensionClient(
request *restful.Request,
response *restful.Response,
) (apiextensionsclientset.Interface, error) {
apiExtClient, err := client.APIExtensionClient(request.Request)
if err != nil {
errors.HandleInternalError(response, err)
return nil, err
}
return apiExtClient, nil
}
func (apiHandler *APIHandler) getKubeEdgeClient(
request *restful.Request,
response *restful.Response,
) (kubeedgeClient.Interface, error) {
kubeEdgeClient, err := client.KubeEdgeClient(request.Request)
if err != nil {
errors.HandleInternalError(response, err)
return nil, err
}
return kubeEdgeClient, nil
}

View File

@ -0,0 +1,101 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubeedge
import (
"fmt"
"go/build"
"os"
"os/exec"
"path/filepath"
"strings"
"k8s.io/klog/v2"
)
func commandExists(command string) (string, bool) {
path, err := exec.LookPath(command)
return path, err == nil
}
func isInContainer() bool {
if _, err := os.Stat("/.dockerenv"); err == nil {
klog.Info(".dockerenv file exists, indicating that the process is running in a Docker container")
return true
}
if data, err := os.ReadFile("/proc/1/cgroup"); err == nil {
text := string(data)
if strings.Contains(text, "docker") || strings.Contains(text, "kubepods") ||
strings.Contains(text, "containerd") {
klog.Info("Cgroup file contains 'docker', 'kubepods', or 'containerd', indicating that the process is running in a container")
return true
}
}
klog.Info("No indication that the process is running in a Docker container")
return false
}
func checkDependencies(hasKeink bool) error {
var commands []string
if hasKeink {
commands = []string{"kubectl", "docker"}
} else {
commands = []string{"kubectl", "git", "make", "docker", "go"}
}
for _, cmd := range commands {
if _, ok := commandExists(cmd); !ok {
klog.Errorf("Command %s not found", cmd)
return fmt.Errorf("command %s not found", cmd)
}
}
klog.Info("All required commands are available")
return nil
}
func getKeinkPath() (string, bool) {
if path, ok := commandExists("keink"); ok {
return path, true
}
binDir := filepath.Join(build.Default.GOPATH, "src", "github.com", "kubeedge", "keink", "bin", "keink")
if _, err := os.Stat(binDir); err == nil {
klog.Infof("Keink binary found at %s", binDir)
return binDir, true
}
return "", false
}
func CheckIsAbleToRunKeink() bool {
if isInContainer() {
klog.Info("Running in a container, unable to run keink")
return false
}
_, hasKeink := getKeinkPath()
if err := checkDependencies(hasKeink); err != nil {
return false
}
return true
}

View File

@ -0,0 +1,220 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubeedge
import (
"bufio"
"fmt"
"go/build"
"os"
"os/exec"
"path/filepath"
"golang.org/x/tools/go/packages"
"k8s.io/klog/v2"
)
func executeCommand(ch chan string, command string, args ...string) error {
cmd := exec.Command(command, args...)
errPipe, err := cmd.StderrPipe()
if err != nil {
klog.Errorf("Failed to get stderr pipe: %v", err)
return err
}
outPipe, err := cmd.StdoutPipe()
if err != nil {
klog.Errorf("Failed to get stdout pipe: %v", err)
return err
}
if err := cmd.Start(); err != nil {
klog.Errorf("Failed to start command: %v", err)
return err
}
go func() {
scanner := bufio.NewScanner(errPipe)
for scanner.Scan() {
ch <- scanner.Text()
}
}()
go func() {
scanner := bufio.NewScanner(outPipe)
for scanner.Scan() {
ch <- scanner.Text()
}
}()
if err := cmd.Wait(); err != nil {
klog.Errorf("Command execution failed: %v", err)
return err
}
return nil
}
func findOrCloneKeink(ch chan string) error {
localDir := filepath.Join(build.Default.GOPATH, "src", "github.com", "kubeedge", "keink")
if _, err := os.Stat(localDir); err == nil {
klog.Infof("Loading keink package from %s", localDir)
ch <- fmt.Sprintf("Loading keink package from %s", localDir)
pkg, err := packages.Load(&packages.Config{Mode: packages.NeedName | packages.NeedFiles}, localDir)
if err != nil {
klog.Errorf("Failed to load keink package: %v", err)
return fmt.Errorf("failed to load keink package: %v", err)
} else if len(pkg) > 0 && pkg[0].PkgPath != "" {
klog.Infof("Found keink package at %s", pkg[0].PkgPath)
return nil
}
}
klog.Infof("Cloning keink repository to %s", localDir)
if err := executeCommand(ch, "git", "clone", "https://github.com/kubeedge/keink.git",
"--depth=1", localDir); err != nil {
klog.Errorf("Failed to clone keink repository: %v", err)
return fmt.Errorf("failed to clone keink repository: %v", err)
}
klog.Infof("Cloned keink repository to %s", localDir)
return nil
}
func installGoDependencies(ch chan string) error {
klog.Info("Installing Go dependencies...")
if err := executeCommand(ch, "go", "mod", "tidy"); err != nil {
return fmt.Errorf("failed to install Go dependencies: %v", err)
}
klog.Info("Successfully installed Go dependencies")
return nil
}
func makeKeink(ch chan string) error {
klog.Info("Building keink...")
if err := executeCommand(ch, "make"); err != nil {
return fmt.Errorf("failed to run make: %v", err)
}
klog.Info("Successfully built keink")
return nil
}
func buildKeink(ch chan string) error {
if err := findOrCloneKeink(ch); err != nil {
return err
}
cwd := os.Getenv("PWD")
defer os.Chdir(cwd)
destDir := filepath.Join(build.Default.GOPATH, "src", "github.com", "kubeedge", "keink")
if err := os.Chdir(destDir); err != nil {
klog.Errorf("Failed to change directory to keink: %v", err)
return fmt.Errorf("failed to change directory to keink: %v", err)
}
if err := installGoDependencies(ch); err != nil {
return err
}
if err := makeKeink(ch); err != nil {
return err
}
return nil
}
func buildEdgeImage(ch chan string, keinkPath string) error {
// Check image existence
if err := executeCommand(ch, "docker", "inspect", "kubeedge/node:latest"); err == nil {
klog.Info("Image kubeedge/node:latest already exists, skipping build")
return nil
}
klog.Info("Building edge image...")
if err := executeCommand(ch, keinkPath, "build", "edge-image"); err != nil {
return fmt.Errorf("failed to build edge image: %v", err)
}
klog.Info("Successfully built edge image")
return nil
}
func runKubeEdge(ch chan string, keinkPath string) error {
klog.Info("Running kubeedge...")
if err := executeCommand(ch, keinkPath, "create", "kubeedge", "--image",
"kubeedge/node:latest", "--wait", "120s"); err != nil {
return fmt.Errorf("failed to run kubeedge: %v", err)
}
klog.Info("Successfully created kubeedge")
return nil
}
func runKeink(ch chan string, keinkPath string) error {
if err := buildEdgeImage(ch, keinkPath); err != nil {
return err
}
if err := runKubeEdge(ch, keinkPath); err != nil {
return err
}
return nil
}
func RunKubeEdgeByKeink() (chan string, chan error, error) {
isAbleToRun := CheckIsAbleToRunKeink()
if !isAbleToRun {
return nil, nil, fmt.Errorf("unable to run Keink to create kubeedge")
}
keinkPath, hasKeink := getKeinkPath()
if err := checkDependencies(hasKeink); err != nil {
return nil, nil, err
}
ch := make(chan string)
errChan := make(chan error)
go func() {
defer close(ch)
defer func() {
errChan <- nil
close(errChan)
}()
if !hasKeink {
if err := buildKeink(ch); err != nil {
errChan <- err
return
}
keinkPath = filepath.Join(build.Default.GOPATH, "src", "github.com", "kubeedge", "keink", "bin", "keink")
}
if err := runKeink(ch, keinkPath); err != nil {
errChan <- err
return
}
}()
return ch, errChan, nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clusterrole
import (
"context"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetClusterRoleList(client k8sClient.Interface) (*rbacv1.ClusterRoleList, error) {
klog.V(4).Info("Getting cluster role list")
list, err := client.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get cluster role list: %v", err)
return nil, err
}
return list, nil
}
func GetClusterRole(client k8sClient.Interface, name string) (*rbacv1.ClusterRole, error) {
klog.V(4).Infof("Getting cluster role %s", name)
result, err := client.RbacV1().ClusterRoles().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get cluster role %s: %v", name, err)
return nil, err
}
return result, nil
}
func CreateClusterRole(client k8sClient.Interface, clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) {
klog.V(4).Infof("Creating cluster role %s", clusterRole.Name)
result, err := client.RbacV1().ClusterRoles().Create(context.TODO(), clusterRole, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create cluster role %s: %v", clusterRole.Name, err)
return nil, err
}
return result, nil
}
func UpdateClusterRole(client k8sClient.Interface, clusterRole *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) {
klog.V(4).Infof("Updating cluster role %s", clusterRole.Name)
result, err := client.RbacV1().ClusterRoles().Update(context.TODO(), clusterRole, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update cluster role %s: %v", clusterRole.Name, err)
return nil, err
}
return result, nil
}
func DeleteClusterRole(client k8sClient.Interface, name string) error {
klog.V(4).Infof("Deleting cluster role %s", name)
err := client.RbacV1().ClusterRoles().Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete cluster role %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package clusterrolebinding
import (
"context"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetClusterRoleBindingList(client k8sClient.Interface) (*rbacv1.ClusterRoleBindingList, error) {
klog.V(4).Info("Getting cluster role binding list")
list, err := client.RbacV1().ClusterRoleBindings().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get cluster role binding list: %v", err)
return nil, err
}
return list, nil
}
func GetClusterRoleBinding(client k8sClient.Interface, name string) (*rbacv1.ClusterRoleBinding, error) {
klog.V(4).Infof("Getting cluster role binding %s", name)
result, err := client.RbacV1().ClusterRoleBindings().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get cluster role binding %s: %v", name, err)
return nil, err
}
return result, nil
}
func CreateClusterRoleBinding(client k8sClient.Interface, clusterRoleBinding *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) {
klog.V(4).Infof("Creating cluster role binding %s", clusterRoleBinding.Name)
result, err := client.RbacV1().ClusterRoleBindings().Create(context.TODO(), clusterRoleBinding, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create cluster role binding %s: %v", clusterRoleBinding.Name, err)
return nil, err
}
return result, nil
}
func UpdateClusterRoleBinding(client k8sClient.Interface, clusterRoleBinding *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) {
klog.V(4).Infof("Updating cluster role binding %s", clusterRoleBinding.Name)
result, err := client.RbacV1().ClusterRoleBindings().Update(context.TODO(), clusterRoleBinding, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update cluster role binding %s: %v", clusterRoleBinding.Name, err)
return nil, err
}
return result, nil
}
func DeleteClusterRoleBinding(client k8sClient.Interface, name string) error {
klog.V(4).Infof("Deleting cluster role binding %s", name)
err := client.RbacV1().ClusterRoleBindings().Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete cluster role binding %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,35 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package common
import (
"k8s.io/apimachinery/pkg/version"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetVersion(client k8sClient.Interface) (*version.Info, error) {
klog.V(4).Info("Getting kubernetes version")
version, err := client.Discovery().ServerVersion()
if err != nil {
klog.Errorf("Failed to get kubernetes version: %v", err)
return nil, err
}
return version, nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package configmap
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetConfigMapList(client k8sClient.Interface, namespace string) (*corev1.ConfigMapList, error) {
klog.V(4).Info("Getting config map list")
list, err := client.CoreV1().ConfigMaps(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get config map list: %v", err)
return nil, err
}
return list, nil
}
func GetConfigMap(client k8sClient.Interface, namespace, name string) (*corev1.ConfigMap, error) {
klog.V(4).Infof("Getting config map %s in namespace %s", name, namespace)
result, err := client.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get config map %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return result, nil
}
func CreateConfigMap(client k8sClient.Interface, namespace string, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) {
klog.V(4).Infof("Creating config map %s in namespace %s", configMap.Name, namespace)
result, err := client.CoreV1().ConfigMaps(namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create config map %s in namespace %s: %v", configMap.Name, namespace, err)
return nil, err
}
return result, nil
}
func UpdateConfigMap(client k8sClient.Interface, namespace string, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) {
klog.V(4).Infof("Updating config map %s in namespace %s", configMap.Name, namespace)
result, err := client.CoreV1().ConfigMaps(namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update config map %s in namespace %s: %v", configMap.Name, namespace, err)
return nil, err
}
return result, nil
}
func DeleteConfigMap(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting config map %s in namespace %s", name, namespace)
err := client.CoreV1().ConfigMaps(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete config map %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package crd
import (
"context"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetCRDList(client apiextensionsclientset.Interface) (*apiextensionsv1.CustomResourceDefinitionList, error) {
klog.V(4).Info("Getting CRD list")
list, err := client.ApiextensionsV1().CustomResourceDefinitions().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get CRD list: %v", err)
return nil, err
}
return list, nil
}
func GetCRD(client apiextensionsclientset.Interface, name string) (*apiextensionsv1.CustomResourceDefinition, error) {
klog.V(4).Infof("Getting CRD %s", name)
result, err := client.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get CRD %s: %v", name, err)
return nil, err
}
return result, nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package deployment
import (
"context"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetDeploymentList(client k8sClient.Interface, namespace string) (*appsv1.DeploymentList, error) {
klog.V(4).Info("Getting deployment list")
list, err := client.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get deployment list: %v", err)
return nil, err
}
return list, nil
}
func GetDeployment(client k8sClient.Interface, namespace, name string) (*appsv1.Deployment, error) {
klog.V(4).Infof("Getting deployment %s in namespace %s", name, namespace)
deployment, err := client.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get deployment %s: %v", name, err)
return nil, err
}
return deployment, nil
}
func CreateDeployment(client k8sClient.Interface, namespace string, deployment *appsv1.Deployment) (*appsv1.Deployment, error) {
klog.V(4).Infof("Creating deployment %s in namespace %s", deployment.Name, namespace)
createdDeployment, err := client.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create deployment %s: %v", deployment.Name, err)
return nil, err
}
return createdDeployment, nil
}
func UpdateDeployment(client k8sClient.Interface, namespace string, deployment *appsv1.Deployment) (*appsv1.Deployment, error) {
klog.V(4).Infof("Updating deployment %s in namespace %s", deployment.Name, namespace)
updatedDeployment, err := client.AppsV1().Deployments(namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update deployment %s: %v", deployment.Name, err)
return nil, err
}
return updatedDeployment, nil
}
func DeleteDeployment(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting deployment %s in namespace %s", name, namespace)
err := client.AppsV1().Deployments(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete deployment %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package device
import (
"context"
devicev1beta1 "github.com/kubeedge/api/apis/devices/v1beta1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetDeviceList(client kubeedgeClient.Interface, namespace string) (*devicev1beta1.DeviceList, error) {
klog.V(4).Info("Getting device list")
list, err := client.DevicesV1beta1().Devices(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get device list: %v", err)
return nil, err
}
return list, nil
}
func GetDevice(client kubeedgeClient.Interface, namespace, name string) (*devicev1beta1.Device, error) {
klog.V(4).Infof("Getting device %s in namespace %s", name, namespace)
device, err := client.DevicesV1beta1().Devices(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get device %s: %v", name, err)
return nil, err
}
return device, nil
}
func CreateDevice(client kubeedgeClient.Interface, namespace string, device *devicev1beta1.Device) (*devicev1beta1.Device, error) {
klog.V(4).Infof("Creating device %s in namespace %s", device.Name, namespace)
createdDevice, err := client.DevicesV1beta1().Devices(namespace).Create(context.TODO(), device, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create device %s: %v", device.Name, err)
return nil, err
}
return createdDevice, nil
}
func UpdateDevice(client kubeedgeClient.Interface, namespace string, device *devicev1beta1.Device) (*devicev1beta1.Device, error) {
klog.V(4).Infof("Updating device %s in namespace %s", device.Name, namespace)
updatedDevice, err := client.DevicesV1beta1().Devices(namespace).Update(context.TODO(), device, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update device %s: %v", device.Name, err)
return nil, err
}
return updatedDevice, nil
}
func DeleteDevice(client kubeedgeClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting device %s in namespace %s", name, namespace)
err := client.DevicesV1beta1().Devices(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete device %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package devicemodel
import (
"context"
devicev1beta1 "github.com/kubeedge/api/apis/devices/v1beta1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetDeviceModelList(client kubeedgeClient.Interface, namespace string) (*devicev1beta1.DeviceModelList, error) {
klog.V(4).Info("Getting device model list")
list, err := client.DevicesV1beta1().DeviceModels(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get device model list: %v", err)
return nil, err
}
return list, nil
}
func GetDeviceModel(client kubeedgeClient.Interface, namespace, name string) (*devicev1beta1.DeviceModel, error) {
klog.V(4).Infof("Getting device model %s in namespace %s", name, namespace)
deviceModel, err := client.DevicesV1beta1().DeviceModels(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get device model %s: %v", name, err)
return nil, err
}
return deviceModel, nil
}
func CreateDeviceModel(client kubeedgeClient.Interface, namespace string, deviceModel *devicev1beta1.DeviceModel) (*devicev1beta1.DeviceModel, error) {
klog.V(4).Infof("Creating device model %s in namespace %s", deviceModel.Name, namespace)
createdDeviceModel, err := client.DevicesV1beta1().DeviceModels(namespace).Create(context.TODO(), deviceModel, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create device model %s: %v", deviceModel.Name, err)
return nil, err
}
return createdDeviceModel, nil
}
func UpdateDeviceModel(client kubeedgeClient.Interface, namespace string, deviceModel *devicev1beta1.DeviceModel) (*devicev1beta1.DeviceModel, error) {
klog.V(4).Infof("Updating device model %s in namespace %s", deviceModel.Name, namespace)
updatedDeviceModel, err := client.DevicesV1beta1().DeviceModels(namespace).Update(context.TODO(), deviceModel, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update device model %s: %v", deviceModel.Name, err)
return nil, err
}
return updatedDeviceModel, nil
}
func DeleteDeviceModel(client kubeedgeClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting device model %s in namespace %s", name, namespace)
err := client.DevicesV1beta1().DeviceModels(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete device model %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package edgeapplication
import (
"context"
appsv1alpha1 "github.com/kubeedge/api/apis/apps/v1alpha1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetEdgeApplicationList(client kubeedgeClient.Interface, namespace string) (*appsv1alpha1.EdgeApplicationList, error) {
klog.V(4).Info("Getting edge application list")
list, err := client.AppsV1alpha1().EdgeApplications(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get edge application list: %v", err)
return nil, err
}
return list, nil
}
func GetEdgeApplication(client kubeedgeClient.Interface, namespace, name string) (*appsv1alpha1.EdgeApplication, error) {
klog.V(4).Infof("Getting edge application %s in namespace %s", name, namespace)
edgeApplication, err := client.AppsV1alpha1().EdgeApplications(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get edge application %s: %v", name, err)
return nil, err
}
return edgeApplication, nil
}
func CreateEdgeApplication(client kubeedgeClient.Interface, namespace string, edgeApplication *appsv1alpha1.EdgeApplication) (*appsv1alpha1.EdgeApplication, error) {
klog.V(4).Infof("Creating edge application %s in namespace %s", edgeApplication.Name, namespace)
createdEdgeApplication, err := client.AppsV1alpha1().EdgeApplications(namespace).Create(context.TODO(), edgeApplication, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create edge application %s: %v", edgeApplication.Name, err)
return nil, err
}
return createdEdgeApplication, nil
}
func UpdateEdgeApplication(client kubeedgeClient.Interface, namespace string, edgeApplication *appsv1alpha1.EdgeApplication) (*appsv1alpha1.EdgeApplication, error) {
klog.V(4).Infof("Updating edge application %s in namespace %s", edgeApplication.Name, namespace)
updatedEdgeApplication, err := client.AppsV1alpha1().EdgeApplications(namespace).Update(context.TODO(), edgeApplication, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update edge application %s: %v", edgeApplication.Name, err)
return nil, err
}
return updatedEdgeApplication, nil
}
func DeleteEdgeApplication(client kubeedgeClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting edge application %s in namespace %s", name, namespace)
err := client.AppsV1alpha1().EdgeApplications(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete edge application %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,38 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package namespace
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetNamespaceList(client k8sClient.Interface) (*corev1.NamespaceList, error) {
klog.V(4).Info("Getting namespace list")
list, err := client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get namespace list: %v", err)
return nil, err
}
return list, nil
}

View File

@ -0,0 +1,74 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package node
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetNodeList(client k8sClient.Interface) (*corev1.NodeList, error) {
klog.V(4).Info("Getting node list")
list, err := client.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get node list: %v", err)
return nil, err
}
return list, nil
}
func GetNode(client k8sClient.Interface, name string) (*corev1.Node, error) {
klog.V(4).Infof("Getting node %s", name)
result, err := client.CoreV1().Nodes().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get node %s: %v", name, err)
return nil, err
}
return result, nil
}
func UpdateNode(client k8sClient.Interface, node *corev1.Node) (*corev1.Node, error) {
klog.V(4).Infof("Updating node %s", node.Name)
result, err := client.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update node %s: %v", node.Name, err)
return nil, err
}
return result, nil
}
func DeleteNode(client k8sClient.Interface, name string) error {
klog.V(4).Infof("Deleting node %s", name)
err := client.CoreV1().Nodes().Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete node %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package nodegroup
import (
"context"
appsv1alpha1 "github.com/kubeedge/api/apis/apps/v1alpha1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetNodeGroupList(client kubeedgeClient.Interface) (*appsv1alpha1.NodeGroupList, error) {
klog.V(4).Info("Getting node group list")
list, err := client.AppsV1alpha1().NodeGroups().List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get node group list: %v", err)
return nil, err
}
return list, nil
}
func GetNodeGroup(client kubeedgeClient.Interface, name string) (*appsv1alpha1.NodeGroup, error) {
klog.V(4).Infof("Getting node group %s", name)
nodeGroup, err := client.AppsV1alpha1().NodeGroups().Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get node group %s: %v", name, err)
return nil, err
}
return nodeGroup, nil
}
func CreateNodeGroup(client kubeedgeClient.Interface, nodeGroup *appsv1alpha1.NodeGroup) (*appsv1alpha1.NodeGroup, error) {
klog.V(4).Infof("Creating node group %s", nodeGroup.Name)
createdNodeGroup, err := client.AppsV1alpha1().NodeGroups().Create(context.TODO(), nodeGroup, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create node group %s: %v", nodeGroup.Name, err)
return nil, err
}
return createdNodeGroup, nil
}
func UpdateNodeGroup(client kubeedgeClient.Interface, nodeGroup *appsv1alpha1.NodeGroup) (*appsv1alpha1.NodeGroup, error) {
klog.V(4).Infof("Updating node group %s", nodeGroup.Name)
updatedNodeGroup, err := client.AppsV1alpha1().NodeGroups().Update(context.TODO(), nodeGroup, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update node group %s: %v", nodeGroup.Name, err)
return nil, err
}
return updatedNodeGroup, nil
}
func DeleteNodeGroup(client kubeedgeClient.Interface, name string) error {
klog.V(4).Infof("Deleting node group %s", name)
err := client.AppsV1alpha1().NodeGroups().Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete node group %s: %v", name, err)
return err
}
return nil
}

View File

@ -0,0 +1,38 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package pod
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetPodList(client k8sClient.Interface, namespace string) (*corev1.PodList, error) {
klog.V(4).Info("Getting pod list")
list, err := client.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get pod list: %v", err)
return nil, err
}
return list, nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package role
import (
"context"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetRoleList(client k8sClient.Interface, namespace string) (*rbacv1.RoleList, error) {
klog.V(4).Info("Getting role list")
list, err := client.RbacV1().Roles(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get role list: %v", err)
return nil, err
}
return list, nil
}
func GetRole(client k8sClient.Interface, namespace, name string) (*rbacv1.Role, error) {
klog.V(4).Infof("Getting role %s in namespace %s", name, namespace)
result, err := client.RbacV1().Roles(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get role %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return result, nil
}
func CreateRole(client k8sClient.Interface, namespace string, role *rbacv1.Role) (*rbacv1.Role, error) {
klog.V(4).Infof("Creating role %s in namespace %s", role.Name, namespace)
result, err := client.RbacV1().Roles(namespace).Create(context.TODO(), role, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create role %s in namespace %s: %v", role.Name, namespace, err)
return nil, err
}
return result, nil
}
func UpdateRole(client k8sClient.Interface, namespace string, role *rbacv1.Role) (*rbacv1.Role, error) {
klog.V(4).Infof("Updating role %s in namespace %s", role.Name, namespace)
result, err := client.RbacV1().Roles(namespace).Update(context.TODO(), role, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update role %s in namespace %s: %v", role.Name, namespace, err)
return nil, err
}
return result, nil
}
func DeleteRole(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting role %s in namespace %s", name, namespace)
err := client.RbacV1().Roles(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete role %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rolebinding
import (
"context"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetRoleBindingList(client k8sClient.Interface, namespace string) (*rbacv1.RoleBindingList, error) {
klog.V(4).Info("Getting role binding list")
list, err := client.RbacV1().RoleBindings(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get role binding list: %v", err)
return nil, err
}
return list, nil
}
func GetRoleBinding(client k8sClient.Interface, namespace, name string) (*rbacv1.RoleBinding, error) {
klog.V(4).Infof("Getting role binding %s in namespace %s", name, namespace)
roleBinding, err := client.RbacV1().RoleBindings(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get role binding %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return roleBinding, nil
}
func CreateRoleBinding(client k8sClient.Interface, namespace string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) {
klog.V(4).Infof("Creating role binding %s in namespace %s", roleBinding.Name, namespace)
createdRoleBinding, err := client.RbacV1().RoleBindings(namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create role binding %s in namespace %s: %v", roleBinding.Name, namespace, err)
return nil, err
}
return createdRoleBinding, nil
}
func UpdateRoleBinding(client k8sClient.Interface, namespace string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) {
klog.V(4).Infof("Updating role binding %s in namespace %s", roleBinding.Name, namespace)
updatedRoleBinding, err := client.RbacV1().RoleBindings(namespace).Update(context.TODO(), roleBinding, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update role binding %s in namespace %s: %v", roleBinding.Name, namespace, err)
return nil, err
}
return updatedRoleBinding, nil
}
func DeleteRoleBinding(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting role binding %s in namespace %s", name, namespace)
err := client.RbacV1().RoleBindings(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete role binding %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rule
import (
"context"
rulev1 "github.com/kubeedge/api/apis/rules/v1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetRuleList(client kubeedgeClient.Interface, namespace string) (*rulev1.RuleList, error) {
klog.V(4).Info("Getting rule list")
list, err := client.RulesV1().Rules(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get rule list: %v", err)
return nil, err
}
return list, nil
}
func GetRule(client kubeedgeClient.Interface, namespace, name string) (*rulev1.Rule, error) {
klog.V(4).Infof("Getting rule %s in namespace %s", name, namespace)
rule, err := client.RulesV1().Rules(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get rule %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return rule, nil
}
func CreateRule(client kubeedgeClient.Interface, namespace string, rule *rulev1.Rule) (*rulev1.Rule, error) {
klog.V(4).Infof("Creating rule %s in namespace %s", rule.Name, namespace)
createdRule, err := client.RulesV1().Rules(namespace).Create(context.TODO(), rule, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create rule %s in namespace %s: %v", rule.Name, namespace, err)
return nil, err
}
return createdRule, nil
}
func UpdateRule(client kubeedgeClient.Interface, namespace string, rule *rulev1.Rule) (*rulev1.Rule, error) {
klog.V(4).Infof("Updating rule %s in namespace %s", rule.Name, namespace)
updatedRule, err := client.RulesV1().Rules(namespace).Update(context.TODO(), rule, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update rule %s in namespace %s: %v", rule.Name, namespace, err)
return nil, err
}
return updatedRule, nil
}
func DeleteRule(client kubeedgeClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting rule %s in namespace %s", name, namespace)
err := client.RulesV1().Rules(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete rule %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package ruleendpoint
import (
"context"
rulev1 "github.com/kubeedge/api/apis/rules/v1"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
func GetRuleEndpointList(client kubeedgeClient.Interface, namespace string) (*rulev1.RuleEndpointList, error) {
klog.V(4).Info("Getting rule endpoint list")
list, err := client.RulesV1().RuleEndpoints(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get rule endpoint list: %v", err)
return nil, err
}
return list, nil
}
func GetRuleEndpoint(client kubeedgeClient.Interface, namespace, name string) (*rulev1.RuleEndpoint, error) {
klog.V(4).Infof("Getting rule endpoint %s in namespace %s", name, namespace)
ruleEndpoint, err := client.RulesV1().RuleEndpoints(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get rule endpoint %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return ruleEndpoint, nil
}
func CreateRuleEndpoint(client kubeedgeClient.Interface, namespace string, ruleEndpoint *rulev1.RuleEndpoint) (*rulev1.RuleEndpoint, error) {
klog.V(4).Infof("Creating rule endpoint %s in namespace %s", ruleEndpoint.Name, namespace)
createdRuleEndpoint, err := client.RulesV1().RuleEndpoints(namespace).Create(context.TODO(), ruleEndpoint, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create rule endpoint %s in namespace %s: %v", ruleEndpoint.Name, namespace, err)
return nil, err
}
return createdRuleEndpoint, nil
}
func UpdateRuleEndpoint(client kubeedgeClient.Interface, namespace string, ruleEndpoint *rulev1.RuleEndpoint) (*rulev1.RuleEndpoint, error) {
klog.V(4).Infof("Updating rule endpoint %s in namespace %s", ruleEndpoint.Name, namespace)
updatedRuleEndpoint, err := client.RulesV1().RuleEndpoints(namespace).Update(context.TODO(), ruleEndpoint, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update rule endpoint %s in namespace %s: %v", ruleEndpoint.Name, namespace, err)
return nil, err
}
return updatedRuleEndpoint, nil
}
func DeleteRuleEndpoint(client kubeedgeClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting rule endpoint %s in namespace %s", name, namespace)
err := client.RulesV1().RuleEndpoints(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete rule endpoint %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package secret
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetSecretList(client k8sClient.Interface, namespace string) (*corev1.SecretList, error) {
klog.V(4).Info("Getting secret list")
list, err := client.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get secret list: %v", err)
return nil, err
}
return list, nil
}
func GetSecret(client k8sClient.Interface, namespace, name string) (*corev1.Secret, error) {
klog.V(4).Infof("Getting secret %s in namespace %s", name, namespace)
result, err := client.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get secret %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return result, nil
}
func CreateSecret(client k8sClient.Interface, namespace string, secret *corev1.Secret) (*corev1.Secret, error) {
klog.V(4).Infof("Creating secret %s in namespace %s", secret.Name, namespace)
result, err := client.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create secret %s in namespace %s: %v", secret.Name, namespace, err)
return nil, err
}
return result, nil
}
func UpdateSecret(client k8sClient.Interface, namespace string, secret *corev1.Secret) (*corev1.Secret, error) {
klog.V(4).Infof("Updating secret %s in namespace %s", secret.Name, namespace)
result, err := client.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update secret %s in namespace %s: %v", secret.Name, namespace, err)
return nil, err
}
return result, nil
}
func DeleteSecret(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting secret %s in namespace %s", name, namespace)
err := client.CoreV1().Secrets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete secret %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package service
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetServiceList(client k8sClient.Interface, namespace string) (*corev1.ServiceList, error) {
klog.V(4).Info("Getting service list")
list, err := client.CoreV1().Services(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get service list: %v", err)
return nil, err
}
return list, nil
}
func GetService(client k8sClient.Interface, namespace, name string) (*corev1.Service, error) {
klog.V(4).Infof("Getting service %s in namespace %s", name, namespace)
service, err := client.CoreV1().Services(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get service %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return service, nil
}
func CreateService(client k8sClient.Interface, namespace string, service *corev1.Service) (*corev1.Service, error) {
klog.V(4).Infof("Creating service %s in namespace %s", service.Name, namespace)
createdService, err := client.CoreV1().Services(namespace).Create(context.TODO(), service, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create service %s in namespace %s: %v", service.Name, namespace, err)
return nil, err
}
return createdService, nil
}
func UpdateService(client k8sClient.Interface, namespace string, service *corev1.Service) (*corev1.Service, error) {
klog.V(4).Infof("Updating service %s in namespace %s", service.Name, namespace)
updatedService, err := client.CoreV1().Services(namespace).Update(context.TODO(), service, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update service %s in namespace %s: %v", service.Name, namespace, err)
return nil, err
}
return updatedService, nil
}
func DeleteService(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting service %s in namespace %s", name, namespace)
err := client.CoreV1().Services(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete service %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,86 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package serviceaccount
import (
"context"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
)
func GetServiceAccountList(client k8sClient.Interface, namespace string) (*corev1.ServiceAccountList, error) {
klog.V(4).Info("Getting service account list")
list, err := client.CoreV1().ServiceAccounts(namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Errorf("Failed to get service account list: %v", err)
return nil, err
}
return list, nil
}
func GetServiceAccount(client k8sClient.Interface, namespace, name string) (*corev1.ServiceAccount, error) {
klog.V(4).Infof("Getting service account %s in namespace %s", name, namespace)
serviceAccount, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Failed to get service account %s in namespace %s: %v", name, namespace, err)
return nil, err
}
return serviceAccount, nil
}
func CreateServiceAccount(client k8sClient.Interface, namespace string, serviceAccount *corev1.ServiceAccount) (*corev1.ServiceAccount, error) {
klog.V(4).Infof("Creating service account %s in namespace %s", serviceAccount.Name, namespace)
createdServiceAccount, err := client.CoreV1().ServiceAccounts(namespace).Create(context.TODO(), serviceAccount, metav1.CreateOptions{})
if err != nil {
klog.Errorf("Failed to create service account %s in namespace %s: %v", serviceAccount.Name, namespace, err)
return nil, err
}
return createdServiceAccount, nil
}
func UpdateServiceAccount(client k8sClient.Interface, namespace string, serviceAccount *corev1.ServiceAccount) (*corev1.ServiceAccount, error) {
klog.V(4).Infof("Updating service account %s in namespace %s", serviceAccount.Name, namespace)
updatedServiceAccount, err := client.CoreV1().ServiceAccounts(namespace).Update(context.TODO(), serviceAccount, metav1.UpdateOptions{})
if err != nil {
klog.Errorf("Failed to update service account %s in namespace %s: %v", serviceAccount.Name, namespace, err)
return nil, err
}
return updatedServiceAccount, nil
}
func DeleteServiceAccount(client k8sClient.Interface, namespace, name string) error {
klog.V(4).Infof("Deleting service account %s in namespace %s", name, namespace)
err := client.CoreV1().ServiceAccounts(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Failed to delete service account %s in namespace %s: %v", name, namespace, err)
return err
}
return nil
}

View File

@ -0,0 +1,113 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"net/http"
"strings"
kubeedgeClient "github.com/kubeedge/api/client/clientset/versioned"
apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apimachinery/pkg/api/errors"
k8sClient "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/klog/v2"
)
func Client(request *http.Request) (k8sClient.Interface, error) {
config, err := configFromRequest(request)
if err != nil {
klog.Errorf("Failed to create config from request: %v", err)
return nil, err
}
klog.V(4).Infof("Creating Kubernetes client with config: %v", config)
return k8sClient.NewForConfig(config)
}
func APIExtensionClient(request *http.Request) (apiextensionsclientset.Interface, error) {
config, err := configFromRequest(request)
if err != nil {
klog.Errorf("Failed to create config from request: %v", err)
return nil, err
}
klog.V(4).Infof("Creating API extension client with config: %v", config)
return apiextensionsclientset.NewForConfig(config)
}
func KubeEdgeClient(request *http.Request) (kubeedgeClient.Interface, error) {
config, err := configFromRequest(request)
if err != nil {
klog.Errorf("Failed to create config from request: %v", err)
return nil, err
}
klog.V(4).Infof("Creating KubeEdge client with config: %v", config)
return kubeedgeClient.NewForConfig(config)
}
func configFromRequest(request *http.Request) (*rest.Config, error) {
authInfo, err := buildAuthInfo(request)
if err != nil {
return nil, err
}
return buildConfigFromAuthInfo(authInfo)
}
func buildConfigFromAuthInfo(authInfo *api.AuthInfo) (*rest.Config, error) {
cmdCfg := api.NewConfig()
cmdCfg.Clusters["kubernetes"] = &api.Cluster{
Server: baseConfig.Host,
CertificateAuthority: baseConfig.TLSClientConfig.CAFile,
CertificateAuthorityData: baseConfig.TLSClientConfig.CAData,
InsecureSkipTLSVerify: baseConfig.TLSClientConfig.Insecure,
}
cmdCfg.AuthInfos["kubernetes"] = authInfo
cmdCfg.Contexts["kubernetes"] = &api.Context{
Cluster: "kubernetes",
AuthInfo: "kubernetes",
}
cmdCfg.CurrentContext = "kubernetes"
return clientcmd.NewDefaultClientConfig(
*cmdCfg,
&clientcmd.ConfigOverrides{},
).ClientConfig()
}
func buildAuthInfo(request *http.Request) (*api.AuthInfo, error) {
token := strings.TrimPrefix(request.Header.Get("Authorization"), "Bearer ")
if token == "" {
return nil, errors.NewUnauthorized("Unauthorized")
}
authInfo := &api.AuthInfo{
Token: token,
}
return authInfo, nil
}

View File

@ -0,0 +1,52 @@
module github.com/kubeedge/dashboard/client
go 1.23.0
require (
github.com/kubeedge/api v1.20.0
k8s.io/apiextensions-apiserver v0.32.3
k8s.io/apimachinery v0.32.3
k8s.io/client-go v0.32.3
k8s.io/klog/v2 v2.130.1
)
require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.7.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.32.3 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -0,0 +1,158 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubeedge/api v1.20.0 h1:JJ7SPfXAShafeU3mc881SoXY7694MymJ9J6Mq311G+U=
github.com/kubeedge/api v1.20.0/go.mod h1:4lcRzdSMStgrMioacny+xP4e0hEtFILfOlNUz8DD3z8=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA=
github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -0,0 +1,105 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package client
import (
"os"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog/v2"
)
var (
baseConfig *rest.Config
)
type Option func(*configBuilder)
type configBuilder struct {
apiServer string
kubeConfigPath string
insecure bool
}
func newConfigBuilder(opts ...Option) *configBuilder {
builder := new(configBuilder)
for _, opt := range opts {
opt(builder)
}
return builder
}
func (c *configBuilder) buildConfig() (*rest.Config, error) {
if c.apiServer == "" && c.kubeConfigPath == "" {
klog.Info("Using in-cluster config")
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
return config, nil
}
if len(c.kubeConfigPath) > 0 {
klog.InfoS("Using kubeconfig file", "kubeconfig", c.kubeConfigPath)
}
if len(c.apiServer) > 0 {
klog.InfoS("Using API server", "apiServer", c.apiServer)
}
config, err := clientcmd.BuildConfigFromFlags(c.apiServer, c.kubeConfigPath)
if err != nil {
klog.Errorf("Failed to build config from flags: %v", err)
return nil, err
}
config.TLSClientConfig.Insecure = c.insecure
return config, nil
}
func WithAPIServer(apiServer string) Option {
return func(c *configBuilder) {
c.apiServer = apiServer
}
}
func WithInsecure(insecure bool) Option {
return func(c *configBuilder) {
c.insecure = insecure
}
}
func WithKubeConfigPath(kubeConfigPath string) Option {
return func(c *configBuilder) {
c.kubeConfigPath = kubeConfigPath
}
}
func Init(opts ...Option) {
builder := newConfigBuilder(opts...)
config, err := builder.buildConfig()
if err != nil {
klog.Errorf("Failed to build config: %v", err)
os.Exit(1)
}
baseConfig = config
}

View File

@ -0,0 +1,27 @@
module github.com/kubeedge/dashboard/errors
go 1.23.0
require (
github.com/emicklei/go-restful/v3 v3.12.2
k8s.io/apimachinery v0.32.3
)
require (
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/text v0.19.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -0,0 +1,87 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -0,0 +1,44 @@
/*
Copyright 2025 The KubeEdge Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package errors
import (
"net/http"
"github.com/emicklei/go-restful/v3"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func HandleError(err error) (int, error) {
if k8serrors.IsUnauthorized(err) {
return http.StatusUnauthorized, k8serrors.NewUnauthorized("Unauthorized")
}
if k8serrors.IsForbidden(err) {
return http.StatusForbidden, k8serrors.NewForbidden(schema.GroupResource{}, "Forbidden", err)
}
return http.StatusInternalServerError, err
}
func HandleInternalError(response *restful.Response, err error) {
code, err := HandleError(err)
response.AddHeader("Content-Type", "plain/text")
_ = response.WriteError(code, err)
}

7
modules/go.work Normal file
View File

@ -0,0 +1,7 @@
go 1.23.0
use (
./api // github.com/kubeedge/dashboard/api
./common/client // github.com/kubeedge/dashboard/client
./common/errors // github.com/kubeedge/dashboard/errors
)

161
modules/go.work.sum Normal file
View File

@ -0,0 +1,161 @@
cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/cadvisor v0.49.0/go.mod h1:s6Fqwb2KiWG6leCegVhw4KW40tf9f7m+SF1aXiE8Wsk=
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/opencontainers/runc v1.1.13/go.mod h1:R016aXacfp/gwQBYw2FDGa9m+n6atbLWrYY8hNMT/sA=
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28=
go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E=
go.etcd.io/etcd/client/v2 v2.305.16/go.mod h1:h9YxWCzcdvZENbfzBTFCnoNumr2ax3F19sKMqHFmXHE=
go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50=
go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2uNuY=
go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI=
go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
k8s.io/apiserver v0.32.3/go.mod h1:q1x9B8E/WzShF49wh3ADOh6muSfpmFL0I2t+TG0Zdgc=
k8s.io/cloud-provider v0.30.7/go.mod h1:yuxkkxKZ9GDOHVGD9b912J13X1miaq08N0sc6hosH3k=
k8s.io/code-generator v0.32.3/go.mod h1:+mbiYID5NLsBuqxjQTygKM/DAdKpAjvBzrJd64NU1G8=
k8s.io/component-base v0.32.3/go.mod h1:LWi9cR+yPAv7cu2X9rZanTiFKB2kHA+JjmhkKjCZRpI=
k8s.io/cri-api v0.30.7/go.mod h1://4/umPJSW1ISNSNng4OwjpkvswJOQwU8rnkvO8P+xg=
k8s.io/csi-translation-lib v0.30.7/go.mod h1:4Knq/JueaCzJEEOPj8VCP1nlJEseps8CVVscYuhpRF4=
k8s.io/gengo/v2 v2.0.0-20240826214909-a7b603a56eb7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
k8s.io/kms v0.32.3/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
k8s.io/kube-scheduler v0.30.7/go.mod h1:TwRTagHK24obTrepxcdasNC1qub15x6+3OgA/qY3E5c=
k8s.io/kubelet v0.30.7/go.mod h1:TX6TeST2u9xrika8RL8wPG/D8x/ZTz0wT7KrHLIZxIc=
k8s.io/kubernetes v1.30.7/go.mod h1:hV3c+sqOEO0eVqgSo0KW5dOJ6UjGJ2l3Pd9+Qvft8UI=
k8s.io/mount-utils v0.30.7/go.mod h1:9sCVmwGLcV1MPvbZ+rToMDnl1QcGozy+jBPd0MsQLIo=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=

37
modules/web/.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
*lock.yaml
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,33 +4,33 @@ import { request } from '@/helper/request';
import { ClusterRole, ClusterRoleList } from '@/types/clusterRole';
export function useListClusterRoles() {
return useQuery<ClusterRoleList>('listClusterRoles', `/apis/rbac.authorization.k8s.io/v1/clusterroles`, {
return useQuery<ClusterRoleList>('listClusterRoles', `/clusterrole`, {
method: 'GET',
});
}
export function getClusterRole(name: string) {
return request<ClusterRole>(`/apis/rbac.authorization.k8s.io/v1/clusterroles/${name}`, {
return request<ClusterRole>(`/clusterrole/${name}`, {
method: 'GET',
});
}
export function createClusterRole(data: ClusterRole) {
return request<ClusterRole>(`/apis/rbac.authorization.k8s.io/v1/clusterroles`, {
return request<ClusterRole>(`/clusterrole`, {
method: 'POST',
data,
});
}
export function updateClusterRole(name: string, data: ClusterRole) {
return request<ClusterRole>(`/apis/rbac.authorization.k8s.io/v1/clusterroles/${name}`, {
return request<ClusterRole>(`/clusterrole`, {
method: 'PUT',
data,
});
}
export function deleteClusterRole(name: string) {
return request<Status>(`/apis/rbac.authorization.k8s.io/v1/clusterroles/${name}`, {
return request<Status>(`/clusterrole/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,33 +4,33 @@ import { Status } from '@/types/common';
import { request } from '@/helper/request';
export function useListClusterRoleBindings() {
return useQuery<ClusterRoleBindingList>('listClusterRoleBindings', `/apis/rbac.authorization.k8s.io/v1/clusterrolebindings`, {
return useQuery<ClusterRoleBindingList>('listClusterRoleBindings', `/clusterrolebinding`, {
method: 'GET',
});
}
export function getClusterRoleBinding(name: string) {
return request<ClusterRoleBinding>(`/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/${name}`, {
return request<ClusterRoleBinding>(`/clusterrolebinding/${name}`, {
method: 'GET',
});
}
export function createClusterRoleBinding(data: ClusterRoleBinding) {
return request<ClusterRoleBinding>(`/apis/rbac.authorization.k8s.io/v1/clusterrolebindings`, {
return request<ClusterRoleBinding>(`/clusterrolebinding`, {
method: 'POST',
data,
});
}
export function updateClusterRoleBinding(name: string, data: ClusterRoleBinding) {
return request<ClusterRoleBinding>(`/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/${name}`, {
return request<ClusterRoleBinding>(`/clusterrolebinding`, {
method: 'PUT',
data,
});
}
export function deleteClusterRoleBinding(name: string) {
return request<Status>(`/apis/rbac.authorization.k8s.io/v1/clusterrolebindings/${name}`, {
return request<Status>(`/clusterrolebinding/${name}`, {
method: 'DELETE',
});
}

View File

@ -5,34 +5,34 @@ import { request } from '@/helper/request';
export function useListConfigMaps(namespace?: string) {
const url = namespace ? `/api/v1/namespaces/${namespace}/configmaps` : '/api/v1/configmaps'
const url = namespace ? `/configmap/${namespace}` : '/configmap';
return useQuery<ConfigMapList>('listConfigMaps', url, {
method: 'GET',
});
}
export function getConfigMap(namespace: string, name: string) {
return request<ConfigMap>(`/api/v1/namespaces/${namespace}/configmaps/${name}`, {
return request<ConfigMap>(`/configmap/${namespace}/${name}`, {
method: 'GET',
});
}
export function createConfigMap(namespace: string, data: ConfigMap) {
return request<ConfigMap>(`/api/v1/namespaces/${namespace}/configmaps`, {
return request<ConfigMap>(`/configmap/${namespace}`, {
method: 'POST',
data,
});
}
export function updateConfigMap(namespace: string, name: string, data: ConfigMap) {
return request<ConfigMap>(`/api/v1/namespaces/${namespace}/configmaps/${name}`, {
return request<ConfigMap>(`/configmap/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteConfigMap(namespace: string, name: string) {
return request<Status>(`/api/v1/namespaces/${namespace}/configmaps/${name}`, {
return request<Status>(`/configmap/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -3,13 +3,13 @@ import { useQuery } from '@/hook/useQuery';
import { CustomResourceDefinition, CustomResourceDefinitionList } from '@/types/customResourceDefinition';
export function useListCustomResourceDefinitions() {
return useQuery<CustomResourceDefinitionList>('listCustomResourceDefinitions', '/apis/apiextensions.k8s.io/v1/customresourcedefinitions', {
return useQuery<CustomResourceDefinitionList>('listCustomResourceDefinitions', '/crd', {
method: 'GET',
});
}
export function getCustomResourceDefinition(name: string) {
return request<CustomResourceDefinition>(`/apis/apiextensions.k8s.io/v1/customresourcedefinitions/${name}`, {
return request<CustomResourceDefinition>(`/crd/${name}`, {
method: 'GET',
});
}

View File

@ -5,34 +5,34 @@ import { request } from '@/helper/request';
export function useListDeployments(namespace?: string) {
const url = namespace ? `/apis/apps/v1/namespaces/${namespace}/deployments` : '/apis/apps/v1/deployments'
const url = namespace ? `/deployment/${namespace}` : '/deployment';
return useQuery<DeploymentList>('listDeployments', url, {
method: 'GET',
});
}
export function getDeployment(namespace: string, name: string) {
return request<Deployment>(`/apis/apps/v1/namespaces/${namespace}/deployments/${name}`, {
return request<Deployment>(`/deployment/${namespace}/${name}`, {
method: 'GET',
});
}
export function createDeployment(namespace: string, data: Deployment) {
return request<Deployment>(`/apis/apps/v1/namespaces/${namespace}/deployments`, {
return request<Deployment>(`/deployment/${namespace}`, {
method: 'POST',
data,
});
}
export function updateDeployment(namespace: string, name: string, data: Deployment) {
return request<Deployment>(`/apis/apps/v1/namespaces/${namespace}/deployments/${name}`, {
return request<Deployment>(`/deployment/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteDeployment(namespace: string, name: string) {
return request<Status>(`apis/apps/v1/namespaces/${namespace}/deployments/${name}`, {
return request<Status>(`/deployment/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,36 +4,34 @@ import { Device, DeviceList } from '@/types/device';
import { request } from '@/helper/request';
export function useListDevices(namespace?: string) {
const url = namespace
? `/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devices`
: '/apis/devices.kubeedge.io/v1beta1/devices'
const url = namespace ? `/device/${namespace}` : '/device';
return useQuery<DeviceList>('listDevices', url, {
method: 'GET',
});
}
export function getDevice(namespace: string, name: string) {
return request<Device>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devices/${name}`, {
return request<Device>(`/device/${namespace}/${name}`, {
method: 'GET',
});
}
export function createDevice(namespace: string, data: Device) {
return request<Device>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devices`, {
return request<Device>(`/device/${namespace}`, {
method: 'POST',
data,
});
}
export function updateDevice(namespace: string, name: string, data: Device) {
return request<Device>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devices/${name}`, {
return request<Device>(`/device/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteDevice(namespace: string, name: string) {
return request<Status>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devices/${name}`, {
return request<Status>(`/device/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,36 +4,34 @@ import { DeviceModel, DeviceModelList } from '@/types/deviceModel';
import { request } from '@/helper/request';
export function useListDeviceModels(namespace?: string) {
const url = namespace
? `/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devicemodels`
: '/apis/devices.kubeedge.io/v1beta1/devicemodels'
const url = namespace ? `/devicemodel/${namespace}` : 'devicemodel';
return useQuery<DeviceModelList>('listDeviceModels', url, {
method: 'GET',
});
}
export function getDeviceModel(namespace: string, name: string) {
return request<DeviceModel>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devicemodels/${name}`, {
return request<DeviceModel>(`/devicemodel/${namespace}/${name}`, {
method: 'GET',
});
}
export function createDeviceModel(namespace: string, data: DeviceModel) {
return request<DeviceModel>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devicemodels`, {
return request<DeviceModel>(`/devicemodel/${namespace}`, {
method: 'POST',
data,
});
}
export function updateDeviceModel(namespace: string, name: string, data: DeviceModel) {
return request<DeviceModel>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devicemodels/${name}`, {
return request<DeviceModel>(`/devicemodel/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteDeviceModel(namespace: string, name: string) {
return request<Status>(`/apis/devices.kubeedge.io/v1beta1/namespaces/${namespace}/devicemodels/${name}`, {
return request<Status>(`/devicemodel/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,36 +4,34 @@ import { Status } from '@/types/common';
import { EdgeApplication, EdgeApplicationList } from '@/types/edgeApplication';
export function useListEdgeApplications(namespace?: string) {
const url = namespace
? `/apis/apps.kubeedge.io/v1alpha1/namespaces/${namespace}/edgeapplications`
: '/apis/apps.kubeedge.io/v1alpha1/edgeapplications'
const url = namespace ? `/edgeapplication/${namespace}` : '/edgeapplication';
return useQuery<EdgeApplicationList>('listEdgeApplications', url, {
method: 'GET',
});
}
export function getEdgeApplication(namespace: string, name: string) {
return request<EdgeApplication>(`/apis/apps.kubeedge.io/v1alpha1/namespaces/${namespace}/edgeapplications/${name}`, {
return request<EdgeApplication>(`/edgeapplication/${namespace}/${name}`, {
method: 'GET',
});
}
export function createEdgeApplication(namespace: string, data: EdgeApplication) {
return request<EdgeApplication>(`/apis/apps.kubeedge.io/v1alpha1/namespaces/${namespace}/edgeapplications`, {
return request<EdgeApplication>(`/edgeapplication/${namespace}`, {
method: 'POST',
data,
});
}
export function updateEdgeApplication(namespace: string, name: string, data: EdgeApplication) {
return request<EdgeApplication>(`/apis/apps.kubeedge.io/v1alpha1/namespaces/${namespace}/edgeapplications/${name}`, {
return request<EdgeApplication>(`/edgeapplication/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteEdgeApplication(namespace: string, name: string) {
return request<Status>(`/apis/apps.kubeedge.io/v1alpha1/namespaces/${namespace}/edgeapplications/${name}`, {
return request<Status>(`/edgeapplication/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -0,0 +1,16 @@
import { request } from '@/helper/request';
import { useQuery } from '@/hook/useQuery';
export function runKeink() {
return request<string>(`/keink/run`, {
baseURL: '',
method: 'GET',
});
}
export function useKeinkRunnable() {
return useQuery<{ ok: boolean }>('isKeinkRunnable', `/keink/check`, {
baseURL: '',
method: 'GET',
});
}

View File

@ -2,7 +2,7 @@ import { useQuery } from '@/hook/useQuery';
import { NamespaceList } from '@/types/namespace';
export function useListNamespaces() {
return useQuery<NamespaceList>('listNamespaces', '/api/v1/namespaces', {
return useQuery<NamespaceList>('listNamespaces', '/namespace', {
method: 'GET',
});
}

View File

@ -4,26 +4,26 @@ import type { Node, NodeList } from '@/types/node';
import { request } from '@/helper/request';
export function useListNodes() {
return useQuery<NodeList>('listNodes', '/api/v1/nodes', {
return useQuery<NodeList>('listNodes', '/node', {
method: 'GET',
});
}
export function getNode(name: string) {
return request<Node>(`/api/v1/nodes/${name}`, {
return request<Node>(`/node/${name}`, {
method: 'GET',
});
}
export function updateNode(name: string, data: Node) {
return request<Node>(`/api/v1/nodes/${name}`, {
return request<Node>(`/node`, {
method: 'PUT',
data,
});
}
export function deleteNode(name: string) {
return request<Status>(`/api/v1/nodes/${name}`, {
return request<Status>(`/node/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,33 +4,33 @@ import { NodeGroup, NodeGroupList } from '@/types/nodeGroup';
import { request } from '@/helper/request';
export function useListNodeGroups() {
return useQuery<NodeGroupList>('listNodeGroups', '/apis/apps.kubeedge.io/v1alpha1/nodegroups', {
return useQuery<NodeGroupList>('listNodeGroups', '/nodegroup', {
method: 'GET',
});
}
export function getNodeGroup(name: string) {
return request<NodeGroup>(`/apis/apps.kubeedge.io/v1alpha1/nodegroups/${name}`, {
return request<NodeGroup>(`/nodegroup/${name}`, {
method: 'GET',
});
}
export function createNodeGroup(data: NodeGroup) {
return request<NodeGroup>(`/apis/apps.kubeedge.io/v1alpha1/nodegroups`, {
return request<NodeGroup>(`/nodegroup`, {
method: 'POST',
data,
});
}
export function updateNodeGroup(name: string, data: NodeGroup) {
return request<NodeGroup>(`/apis/apps.kubeedge.io/v1alpha1/nodegroups/${name}`, {
return request<NodeGroup>(`/nodegroup`, {
method: 'PUT',
data,
});
}
export function deleteNodeGroup(name: string) {
return request<Status>(`/apis/apps.kubeedge.io/v1alpha1/nodegroups/${name}`, {
return request<Status>(`/nodegroup/${name}`, {
method: 'DELETE',
});
}

View File

@ -2,7 +2,7 @@ import { useQuery } from '@/hook/useQuery';
import { PodList } from '@/types/pod';
export function useListPods(namespace?: string) {
const url = namespace ? `/api/v1/namespaces/${namespace}/pods` : '/api/v1/pods';
const url = namespace ? `/pod/${namespace}` : '/pod';
return useQuery<PodList>('listPods', url, {
method: 'GET',

View File

@ -4,34 +4,34 @@ import { Role, RoleList } from '@/types/role';
import { request } from '@/helper/request';
export function useListRoles(namespace?: string) {
const url = namespace ? `/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/roles` : '/apis/rbac.authorization.k8s.io/v1/roles';
const url = namespace ? `/role/${namespace}` : '/role';
return useQuery<RoleList>('listRoles', url, {
method: 'GET',
});
}
export function getRole(namespace: string, name: string) {
return request<Role>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/roles/${name}`, {
return request<Role>(`/role/${namespace}/${name}`, {
method: 'GET',
});
}
export function createRole(namespace: string, data: Role) {
return request<Role>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/roles`, {
return request<Role>(`/role/${namespace}`, {
method: 'POST',
data,
});
}
export function updateRole(namespace: string, name: string, data: Role) {
return request<Role>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/roles/${name}`, {
return request<Role>(`/role/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteRole(namespace: string, name: string) {
return request<Status>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/roles/${name}`, {
return request<Status>(`/role/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,36 +4,34 @@ import { RoleBinding, RoleBindingList } from '@/types/roleBinding';
import { request } from '@/helper/request';
export function useListRoleBindings(namespace?: string) {
const url = namespace
? `/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/rolebindings`
: '/apis/rbac.authorization.k8s.io/v1/rolebindings';
const url = namespace ? `/rolebinding/${namespace}` : '/rolebinding';
return useQuery<RoleBindingList>('listRoleBindings', url, {
method: 'GET',
});
}
export function getRoleBinding(namespace: string, name: string) {
return request<RoleBinding>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/rolebindings/${name}`, {
return request<RoleBinding>(`/rolebinding/${namespace}/${name}`, {
method: 'GET',
});
}
export function createRoleBinding(namespace: string, data: RoleBinding) {
return request<RoleBinding>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/rolebindings`, {
return request<RoleBinding>(`/rolebinding/${namespace}`, {
method: 'POST',
data,
});
}
export function updateRoleBinding(namespace: string, name: string, data: RoleBinding) {
return request<RoleBinding>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/rolebindings/${name}`, {
return request<RoleBinding>(`/rolebinding/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteRoleBinding(namespace: string, name: string) {
return request<Status>(`/apis/rbac.authorization.k8s.io/v1/namespaces/${namespace}/rolebindings/${name}`, {
return request<Status>(`/rolebinding/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,34 +4,34 @@ import { Rule, RuleList } from '@/types/rule';
import { request } from '@/helper/request';
export function useListRules(namespace?: string) {
const url = namespace ? `/apis/rules.kubeedge.io/v1/namespaces/${namespace}/rules` : '/apis/rules.kubeedge.io/v1/rules';
const url = namespace ? `/rule/${namespace}` : '/rule';
return useQuery<RuleList>('listRules', url, {
method: 'GET',
});
}
export function getRule(namespace: string, name: string) {
return request<Rule>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/rules/${name}`, {
return request<Rule>(`/rule/${namespace}/${name}`, {
method: 'GET',
});
}
export function createRule(namespace: string, data: Rule) {
return request<Rule>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/rules`, {
return request<Rule>(`/rule/${namespace}`, {
method: 'POST',
data,
});
}
export function updateRule(namespace: string, name: string, data: Rule) {
return request<Rule>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/rules/${name}`, {
return request<Rule>(`/rule/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteRule(namespace: string, name: string) {
return request<Status>(`apis/rules.kubeedge.io/v1/namespaces/${namespace}/rules/${name}`, {
return request<Status>(`/rule/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,34 +4,34 @@ import { RuleEndpoint, RuleEndpointList } from '@/types/ruleEndpoint';
import { request } from '@/helper/request';
export function useListRuleEndpoints(namespace?: string) {
const url = namespace ? `/apis/rules.kubeedge.io/v1/namespaces/${namespace}/ruleendpoints` : '/apis/rules.kubeedge.io/v1/ruleendpoints';
const url = namespace ? `/ruleendpoint/${namespace}` : '/ruleendpoint';
return useQuery<RuleEndpointList>('listRuleEndpoints', url, {
method: 'GET',
});
}
export function getRuleEndpoint(namespace: string, name: string) {
return request<RuleEndpoint>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/ruleendpoints/${name}`, {
return request<RuleEndpoint>(`/ruleendpoint/${namespace}/${name}`, {
method: 'GET',
});
}
export function createRuleEndpoint(namespace: string, data: RuleEndpoint) {
return request<RuleEndpoint>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/ruleendpoints`, {
return request<RuleEndpoint>(`/ruleendpoint/${namespace}`, {
method: 'POST',
data,
});
}
export function updateRuleEndpoint(namespace: string, name: string, data: RuleEndpoint) {
return request<RuleEndpoint>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/ruleendpoints/${name}`, {
return request<RuleEndpoint>(`/ruleendpoint/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteRuleEndpoint(namespace: string, name: string) {
return request<Status>(`/apis/rules.kubeedge.io/v1/namespaces/${namespace}/ruleendpoints/${name}`, {
return request<Status>(`/ruleendpoint/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,34 +4,34 @@ import { Secret, SecretList } from '@/types/secret';
import { request } from '@/helper/request';
export function useListSecrets(namespace?: string) {
const url = namespace ? `/api/v1/namespaces/${namespace}/secrets` : '/api/v1/secrets';
const url = namespace ? `/secret/${namespace}` : '/secret';
return useQuery<SecretList>('listSecrets', url, {
method: 'GET',
});
}
export function getSecret(namespace: string, name: string) {
return request<Secret>(`/api/v1/namespaces/${namespace}/secrets/${name}`, {
return request<Secret>(`/secret/${namespace}/${name}`, {
method: 'GET',
});
}
export function createSecret(namespace: string, data: Secret) {
return request<Secret>(`/api/v1/namespaces/${namespace}/secrets`, {
return request<Secret>(`/secret/${namespace}`, {
method: 'POST',
data,
});
}
export function updateSecret(namespace: string, name: string, data: Secret) {
return request<Secret>(`/api/v1/namespaces/${namespace}/secrets/${name}`, {
return request<Secret>(`/secret/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteSecret(namespace: string, name: string) {
return request<Status>(`/api/v1/namespaces/${namespace}/secrets/${name}`, {
return request<Status>(`/secret/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,34 +4,34 @@ import { Service, ServiceList } from '@/types/service';
import { request } from '@/helper/request';
export function useListServices(namespace?: string) {
const url = namespace ? `/api/v1/namespaces/${namespace}/services` : '/api/v1/services';
const url = namespace ? `/service/${namespace}` : '/service';
return useQuery<ServiceList>('listServices', url, {
method: 'GET',
});
}
export function getService(namespace: string, name: string) {
return request<Service>(`/api/v1/namespaces/${namespace}/services/${name}`, {
return request<Service>(`/service/${namespace}/${name}`, {
method: 'GET',
});
}
export function createService(namespace: string, data: Service) {
return request<Service>(`/api/v1/namespaces/${namespace}/services`, {
return request<Service>(`/service/${namespace}`, {
method: 'POST',
data,
});
}
export function updateService(namespace: string, name: string, data: Service) {
return request<Service>(`/api/v1/namespaces/${namespace}/services/${name}`, {
return request<Service>(`/service/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteService(namespace: string, name: string) {
return request<Status>(`/api/v1/namespaces/${namespace}/services/${name}`, {
return request<Status>(`/service/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

@ -4,34 +4,34 @@ import { ServiceAccount, ServiceAccountList } from '@/types/serviceAccount';
import { request } from '@/helper/request';
export function useListServiceAccounts(namespace?: string) {
const url = namespace ? `/api/v1/namespaces/${namespace}/serviceaccounts` : '/api/v1/serviceaccounts';
const url = namespace ? `/serviceaccount/${namespace}` : '/serviceaccount';
return useQuery<ServiceAccountList>('listServiceAccounts', url, {
method: 'GET',
});
}
export function getServiceAccount(namespace: string, name: string) {
return request<ServiceAccount>(`/api/v1/namespaces/${namespace}/serviceaccounts/${name}`, {
return request<ServiceAccount>(`/serviceaccount/${namespace}/${name}`, {
method: 'GET',
});
}
export function createServiceAccount(namespace: string, data: ServiceAccount) {
return request<ServiceAccount>(`/api/v1/namespaces/${namespace}/serviceaccounts`, {
return request<ServiceAccount>(`/serviceaccount/${namespace}`, {
method: 'POST',
data,
});
}
export function updateServiceAccount(namespace: string, name: string, data: ServiceAccount) {
return request<ServiceAccount>(`/api/v1/namespaces/${namespace}/serviceaccounts/${name}`, {
return request<ServiceAccount>(`/serviceaccount/${namespace}`, {
method: 'PUT',
data,
});
}
export function deleteServiceAccount(namespace: string, name: string) {
return request<Status>(`/api/v1/namespaces/${namespace}/serviceaccounts/${name}`, {
return request<Status>(`/serviceaccount/${namespace}/${name}`, {
method: 'DELETE',
});
}

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More