Skip to content

Commit 9fcef88

Browse files
authored
Merge pull request #146 from StatCan/feat/125-go-api-1.6
docs: update backend local debugging and improve experience
2 parents 1ca7a35 + 5726f70 commit 9fcef88

9 files changed

+383
-9
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
coverage_unit.txt
22
jupyter-apis
3+
.vscode
4+
.env
5+
.task
6+
__debug_bin

README.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ A Golang replacement for the **[Kubeflow][kubeflow]** Jupyter Web APIs.
99
See **[CONTRIBUTING.md](CONTRIBUTING.md)**
1010

1111
## Development Environment
12+
***Note that the frontend will report errors when calling `/api/namespaces` when run locally. This***
13+
***issue does not arise in production, as the `/api/namespaces` endpoint is unused.***
14+
15+
To initialize the `.env` file for the development environment, use `task env`.
16+
You will need to fill out your kubeflow cloud account and kubeflow namespace information manually.
17+
The `thunder-tests` folder contains configuration for testing requests against the backend. Use the `vscode`
18+
`THUNDER CLIENT` extension to load the tests.
1219

1320
### Run API Server
1421

@@ -19,15 +26,42 @@ context. See _Connecting a Kubeflow cluster_ below for options.
1926
2. Change directory to project root: `cd jupyter-apis`
2027
3. Run `go run . -spawner-config samples/spawner_ui_config.yaml`
2128

29+
Alternatively,
30+
31+
1. `task go:dev -w -- -spawner-config samples/spawner_ui_config.yaml` will live-reload the Go server upon changes.
32+
33+
_Recommended_
34+
35+
You can use the vscode debugger to run the backend, just copy the below contents to a file at path `.vscode/launch.json`.
36+
```json
37+
{
38+
"version": "0.2.0",
39+
"configurations": [
40+
{
41+
"name": "Debug jupyter-api backend",
42+
"type": "go",
43+
"request": "launch",
44+
"mode": "debug",
45+
"program": ".",
46+
"args": [
47+
"-spawner-config",
48+
"samples/spawner_ui_config.yaml",
49+
],
50+
"envFile": "${workspaceFolder}/.env"
51+
}
52+
]
53+
}
54+
```
55+
2256
### Run Front-End
2357

2458
The front-end is configured to proxy requests to the local API server. It
2559
requires an environment variable (`KF_USER_ID`) to specify the current user –
2660
this is passed to the API server as an HTTP header.
2761

28-
2962
The following can be pasted in a script and executed. This uses the latest node lts version(v16.16.0).
3063
**NOTE**: `user` is when using vagrant. Use the email adress if it is the dev cluser (please never connect to prod directly)
64+
3165
```
3266
cd frontend/common/kubeflow-common-lib
3367
npm i
@@ -44,6 +78,7 @@ KF_USER_ID=user npm start
4478
For the kubecost data to be retrievable, the following will need to be executed `kubectl port-forward -n kubecost-system deployment/kubecost-cost-analyzer 9090`
4579

4680
### Older instructions
81+
4782
1. ~Change directory to front-end folder: `cd frontend`~
4883
2. ~Install dependencies: `npm install`~
4984
3. ~Run the front-end `KF_USER_ID=<cloud_email> npm start`~
@@ -103,3 +138,31 @@ and run `vagrant up`.
103138

104139
[go]: https://golang.org/dl/
105140
[kubeflow]: https://github.com/kubeflow/kubeflow
141+
142+
## Whats Different?
143+
144+
Routes are defined in this repository [here](./main.go).
145+
146+
[Upstream](https://github.com/kubeflow/kubeflow/tree/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes), the endpoints are structures via request type (e.g. `GET`, `PUT`, `DELETE`).
147+
148+
_Note_
149+
150+
- _that not all endpoints are included in the golang implementation_
151+
- _to find the upstream endpoint, load the [Upstream](https://github.com/kubeflow/kubeflow/tree/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes)
152+
and use search with the endpoint text!_
153+
154+
| Request Type | Golang Endpoint | Upstream Python Endpoint | Purpose |
155+
| ------------ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
156+
| GET | /api/config | [/api/config](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/get.py#L9) | |
157+
| GET | /api/gpus | [/api/gpus](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/get.py#L52) | |
158+
| GET | /api/storageclasses/default | [/api/storageclasses/default](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/common/backend/kubeflow/kubeflow/crud_backend/routes/get.py#L26) | |
159+
| GET | /api/namespaces/{namespace}/cost/aggregated | Not found | Get the aggregated kubecost |
160+
| GET | /api/namespaces | [/api/namespaces](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/common/backend/kubeflow/kubeflow/crud_backend/routes/get.py#L10) | Get the list of namespaces |
161+
| GET | /api/namespaces/{namespace} | Not found | Get namespace metadata |
162+
| GET | /api/namespaces/{namespace}/notebooks | [/api/namespaces/\<namespace\>/notebooks](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/get.py#L44) | Get the list of notebooks |
163+
| POST | /api/namespaces/{namespace}/notebooks | [/api/namespaces/\<namespace\>/notebooks](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/default/routes/post.py#L11) | Create a notebook |
164+
| DELETE | /api/namespaces/{namespace}/notebooks/{notebook} | [/api/namespaces/\<namespace\>/notebooks/<notebook>](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/delete.py#L9) | Update a notebook |
165+
| PATCH | /api/namespaces/{namespace}/notebooks/{notebook} | [/api/namespaces/\<namespace\>/notebooks/<notebook](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/patch.py#L19) | Delete a notebook |
166+
| GET | /api/namespaces/{namespace}/pvcs | [/api/namespaces/\<namespace\>/pvc](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/get.py#L15) | List `PVC`s |
167+
| DELETE | /api/namespaces/{namespace}/pvcs/{pvc} | [/api/namespaces/\<namespace\>/pvcs/<pvc>](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/volumes/backend/apps/default/routes/delete.py#L11) | Delete a `PVC` |
168+
| GET | /api/namespaces/{namespace}/poddefaults | [/api/namespaces/\<namespace\>/poddefaults](https://github.com/kubeflow/kubeflow/blob/v1.6.0/components/crud-web-apps/jupyter/backend/apps/common/routes/get.py#L25) | Get `PodDefault`s for a given namespace |

Taskfile.yml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,13 @@ tasks:
7575
desc: Push the built container image
7676
cmds:
7777
- docker push {{.CONTAINER_IMAGE}}
78-
78+
go:dev:
79+
desc: run go code locally for development
80+
cmds:
81+
- go run . {{.CLI_ARGS}}
82+
- sleep 1
83+
sources:
84+
- "*.go"
7985
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/go-task/Taskfile.yml
8086
go:build:
8187
desc: Build the Go code
@@ -163,3 +169,14 @@ tasks:
163169
desc: stop knative environment
164170
cmds:
165171
- "k3d cluster stop {{.CLUSTER_NAME}}"
172+
173+
env:
174+
prefix: ⚙ > env
175+
desc: setup dev environment
176+
cmds:
177+
- echo "KF_NAMESPACE=">>.env
178+
- echo "KF_USER_ID=">>.env
179+
- echo "KF_NOTEBOOK_NAME=swag">>.env
180+
- echo "KF_PVC_NAME=swag">>.env
181+
sources:
182+
- .env

access.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (s *server) checkAccess(subjectAccessReviewTemplate authorizationv1.Subject
7474

7575
// If the user is not permitted, log and return the error and do not process the request
7676
if !resp.Status.Allowed {
77-
msg := fmt.Sprintf("User %s is not permitted to %s %s.%s.%s for namespace: %s", sar.Spec.User, sar.Spec.ResourceAttributes.Verb, sar.Spec.ResourceAttributes.Group, sar.Spec.ResourceAttributes.Version, sar.Spec.ResourceAttributes.Resource, sar.Spec.ResourceAttributes.Namespace)
77+
msg := fmt.Sprintf("User %s is not permitted to %s %s.%s.%s for namespace: '%s'", sar.Spec.User, sar.Spec.ResourceAttributes.Verb, sar.Spec.ResourceAttributes.Group, sar.Spec.ResourceAttributes.Version, sar.Spec.ResourceAttributes.Resource, sar.Spec.ResourceAttributes.Namespace)
7878

7979
log.Println(msg)
8080

main.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"os/signal"
1212
"path"
1313
"path/filepath"
14-
"sync"
1514
"time"
1615

1716
kubeflowv1 "github.com/StatCan/kubeflow-apis/apis/kubeflow/v1"
@@ -54,8 +53,6 @@ type clientsets struct {
5453
}
5554

5655
type server struct {
57-
mux sync.Mutex
58-
5956
Config Configuration
6057

6158
clientsets clientsets
@@ -126,7 +123,7 @@ func main() {
126123
log.Fatal(err)
127124
}
128125

129-
err = s.setupListers(gctx)
126+
_ = s.setupListers(gctx)
130127

131128
// Generate the Gorilla Mux router
132129
router := mux.NewRouter()
@@ -163,8 +160,8 @@ func main() {
163160
Spec: authorizationv1.SubjectAccessReviewSpec{
164161
ResourceAttributes: &authorizationv1.ResourceAttributes{
165162
Group: corev1.SchemeGroupVersion.Group,
166-
Verb: "list",
167-
Resource: "pods",
163+
Verb: "get",
164+
Resource: "namespaces",
168165
Version: corev1.SchemeGroupVersion.Version,
169166
},
170167
},

thunder-tests/thunderActivity.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

thunder-tests/thunderCollection.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"_id": "bf518063-1214-41a0-a602-702e12d98039",
4+
"colName": "Golang Kubeflow",
5+
"created": "2022-09-23T13:47:44.945Z",
6+
"sortNum": 10000,
7+
"folders": [],
8+
"settings": {
9+
"headers": [
10+
{
11+
"name": "kubeflow-userid",
12+
"value": "{{KF_USER_ID}}"
13+
}
14+
],
15+
"tests": [],
16+
"options": {
17+
"baseUrl": "http://localhost:5000"
18+
},
19+
"envId": "0d8a7513-38dd-4e46-93b3-2c0ccb2ee056"
20+
}
21+
}
22+
]

thunder-tests/thunderEnvironment.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"_id": "0d8a7513-38dd-4e46-93b3-2c0ccb2ee056",
4+
"name": "golang-backend",
5+
"default": true,
6+
"sortNum": 10000,
7+
"created": "2022-09-23T13:47:57.807Z",
8+
"modified": "2022-09-23T13:48:16.638Z",
9+
"data": [],
10+
"envFile": "../.env"
11+
}
12+
]

0 commit comments

Comments
 (0)