Skip to content

Commit d06762d

Browse files
fix(ws): update JSON payload for listing workspaces (#134)
* fix(ws): update JSON payload for listing workspaces Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): fix workspaceKind type to POD_TEMPLATE Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): ensure podMetadata labels/annotations are not null Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): fetch and use WorkspaceKind for determining home mount paths Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): fix Volumes.Home values and tests Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): fix PodConfig desired value Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * chore: remove lint warnings by cleaning up comments and formatting Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): refactor workspace model creation to include WorkspaceKind Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> * fix(ws): Move NewWorkspaceModelFromWorkspace from models to repositories Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com> --------- Signed-off-by: mohamedch7 <121046693+mohamedch7@users.noreply.github.com>
1 parent 6fe7716 commit d06762d

File tree

3 files changed

+244
-98
lines changed

3 files changed

+244
-98
lines changed

workspaces/backend/api/workspaces_handler_test.go

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,13 @@ var _ = Describe("Workspaces Handler", func() {
201201
workspace3 := &kubefloworgv1beta1.Workspace{}
202202
Expect(k8sClient.Get(ctx, workspaceKey3, workspace3)).To(Succeed())
203203

204+
workspaceKind := &kubefloworgv1beta1.WorkspaceKind{}
205+
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: workspaceKindName}, workspaceKind)).To(Succeed())
206+
204207
expectedWorkspaces := []models.WorkspaceModel{
205-
models.NewWorkspaceModelFromWorkspace(workspace1),
206-
models.NewWorkspaceModelFromWorkspace(workspace2),
207-
models.NewWorkspaceModelFromWorkspace(workspace3),
208+
repositories.NewWorkspaceModelFromWorkspace(workspace1, workspaceKind),
209+
repositories.NewWorkspaceModelFromWorkspace(workspace2, workspaceKind),
210+
repositories.NewWorkspaceModelFromWorkspace(workspace3, workspaceKind),
208211
}
209212
Expect(workspaces).To(ConsistOf(expectedWorkspaces))
210213

@@ -255,9 +258,12 @@ var _ = Describe("Workspaces Handler", func() {
255258
workspace2 := &kubefloworgv1beta1.Workspace{}
256259
Expect(k8sClient.Get(ctx, workspaceKey2, workspace2)).To(Succeed())
257260

261+
workspaceKind := &kubefloworgv1beta1.WorkspaceKind{}
262+
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: workspaceKindName}, workspaceKind)).To(Succeed())
263+
258264
expectedWorkspaces := []models.WorkspaceModel{
259-
models.NewWorkspaceModelFromWorkspace(workspace1),
260-
models.NewWorkspaceModelFromWorkspace(workspace2),
265+
repositories.NewWorkspaceModelFromWorkspace(workspace1, workspaceKind),
266+
repositories.NewWorkspaceModelFromWorkspace(workspace2, workspaceKind),
261267
}
262268
Expect(workspaces).To(ConsistOf(expectedWorkspaces))
263269

@@ -379,26 +385,60 @@ var _ = Describe("Workspaces Handler", func() {
379385
By("creating the workspace via the API")
380386
workspaceName := "dora"
381387
workspaceModel := models.WorkspaceModel{
382-
Name: workspaceName,
383-
Namespace: namespaceNameCrud,
384-
Paused: false,
388+
Name: workspaceName,
389+
Namespace: namespaceNameCrud,
390+
WorkspaceKind: models.WorkspaceKind{
391+
Name: workspaceKindName,
392+
Type: "POD_TEMPLATE",
393+
},
385394
DeferUpdates: false,
386-
Kind: "jupyterlab",
387-
ImageConfig: "jupyterlab_scipy_190",
388-
PodConfig: "tiny_cpu",
389-
HomeVolume: "workspace-home-bella",
390-
DataVolumes: []models.DataVolumeModel{
391-
{
392-
PvcName: "workspace-data-bella",
393-
MountPath: "/data/my-data",
394-
ReadOnly: false,
395+
Paused: false,
396+
PausedTime: 0,
397+
State: "",
398+
StateMessage: "",
399+
PodTemplate: models.PodTemplate{
400+
PodMetadata: &models.PodMetadata{
401+
Labels: map[string]string{
402+
"app": "dora",
403+
},
404+
Annotations: map[string]string{
405+
"app": "dora",
406+
},
407+
},
408+
Volumes: &models.Volumes{
409+
Home: &models.DataVolumeModel{
410+
PvcName: "my-data-pvc",
411+
MountPath: "/home/jovyan",
412+
ReadOnly: false,
413+
},
414+
Data: []models.DataVolumeModel{
415+
{
416+
PvcName: "my-data-pvc",
417+
MountPath: "/data",
418+
ReadOnly: false,
419+
},
420+
},
421+
},
422+
ImageConfig: &models.ImageConfig{
423+
Current: "WorkspaceKind",
424+
Desired: "", // Status is coming with empty value
425+
RedirectChain: []*models.RedirectChain{},
426+
},
427+
PodConfig: &models.PodConfig{
428+
Current: "WorkspaceKind",
429+
Desired: "WorkspaceKind",
430+
RedirectChain: []*models.RedirectChain{},
395431
},
396432
},
397-
Labels: map[string]string{
398-
"app": "jupyter",
399-
},
400-
Annotations: map[string]string{
401-
"environment": "dev",
433+
Activity: models.Activity{
434+
LastActivity: 0,
435+
LastUpdate: 0,
436+
LastProbe: &models.Probe{
437+
StartTimeMs: 0,
438+
EndTimeMs: 0,
439+
Result: "default_result",
440+
Message: "default_message",
441+
},
402442
},
403443
}
404444

@@ -461,8 +501,7 @@ var _ = Describe("Workspaces Handler", func() {
461501
err = json.Unmarshal(body, &response)
462502
Expect(err).NotTo(HaveOccurred(), "Error unmarshalling response JSON")
463503

464-
// remove auto generated fields from comparison
465-
response.Data.LastActivity = ""
504+
response.Data.Activity.LastActivity = 0
466505

467506
By("checking if the retrieved workspace matches the expected workspace")
468507
retrievedWorkspaceJSON, err := json.Marshal(response.Data)

workspaces/backend/internal/models/workspaces.go

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,71 @@ limitations under the License.
1616

1717
package models
1818

19-
import (
20-
"time"
19+
type WorkspaceModel struct {
20+
Name string `json:"name"`
21+
Namespace string `json:"namespace"`
22+
WorkspaceKind WorkspaceKind `json:"workspace_kind"`
23+
DeferUpdates bool `json:"defer_updates"`
24+
Paused bool `json:"paused"`
25+
PausedTime int64 `json:"paused_time"`
26+
State string `json:"state"`
27+
StateMessage string `json:"state_message"`
28+
PodTemplate PodTemplate `json:"pod_template"`
29+
Activity Activity `json:"activity"`
30+
}
31+
type PodTemplate struct {
32+
PodMetadata *PodMetadata `json:"pod_metadata"`
33+
Volumes *Volumes `json:"volumes"`
34+
ImageConfig *ImageConfig `json:"image_config"`
35+
PodConfig *PodConfig `json:"pod_config"`
36+
}
37+
38+
type PodMetadata struct {
39+
Labels map[string]string `json:"labels"`
40+
Annotations map[string]string `json:"annotations"`
41+
}
42+
type Volumes struct {
43+
Home *DataVolumeModel `json:"home"`
44+
Data []DataVolumeModel `json:"data"`
45+
}
2146

22-
kubefloworgv1beta1 "github.com/kubeflow/notebooks/workspaces/controller/api/v1beta1"
23-
)
47+
type ImageConfig struct {
48+
Current string `json:"current"`
49+
Desired string `json:"desired"`
50+
RedirectChain []*RedirectChain `json:"redirect_chain"`
51+
}
2452

25-
type WorkspaceModel struct {
26-
Namespace string `json:"namespace"`
27-
Name string `json:"name"`
28-
Paused bool `json:"paused"`
29-
DeferUpdates bool `json:"defer_updates"`
30-
Kind string `json:"kind"`
31-
ImageConfig string `json:"image_config"`
32-
PodConfig string `json:"pod_config"`
33-
HomeVolume string `json:"home_volume"`
34-
DataVolumes []DataVolumeModel `json:"data_volumes"`
35-
Labels map[string]string `json:"labels,omitempty"`
36-
Annotations map[string]string `json:"annotations,omitempty"`
37-
Status string `json:"status"`
38-
LastActivity string `json:"last_activity"`
53+
type PodConfig struct {
54+
Current string `json:"current"`
55+
Desired string `json:"desired"`
56+
RedirectChain []*RedirectChain `json:"redirect_chain"`
57+
}
58+
59+
type RedirectChain struct {
60+
Source string `json:"source"`
61+
Target string `json:"target"`
62+
}
63+
64+
type Activity struct {
65+
LastActivity int64 `json:"last_activity"` // Unix Epoch time
66+
LastUpdate int64 `json:"last_update"` // Unix Epoch time
67+
LastProbe *Probe `json:"last_probe"`
68+
}
69+
70+
type Probe struct {
71+
StartTimeMs int64 `json:"start_time_ms"` // Unix Epoch time in milliseconds
72+
EndTimeMs int64 `json:"end_time_ms"` // Unix Epoch time in milliseconds
73+
Result string `json:"result"`
74+
Message string `json:"message"`
75+
}
76+
77+
type WorkspaceKind struct {
78+
Name string `json:"name"`
79+
Type string `json:"type"`
3980
}
4081

4182
type DataVolumeModel struct {
4283
PvcName string `json:"pvc_name"`
4384
MountPath string `json:"mount_path"`
4485
ReadOnly bool `json:"read_only"`
4586
}
46-
47-
func NewWorkspaceModelFromWorkspace(item *kubefloworgv1beta1.Workspace) WorkspaceModel {
48-
t := time.Unix(item.Status.Activity.LastActivity, 0)
49-
formattedLastActivity := t.Format("2006-01-02 15:04:05 MST")
50-
51-
dataVolumes := make([]DataVolumeModel, len(item.Spec.PodTemplate.Volumes.Data))
52-
for i, volume := range item.Spec.PodTemplate.Volumes.Data {
53-
dataVolumes[i] = DataVolumeModel{
54-
PvcName: volume.PVCName,
55-
MountPath: volume.MountPath,
56-
ReadOnly: *volume.ReadOnly,
57-
}
58-
}
59-
// TODO: review all fields
60-
workspaceModel := WorkspaceModel{
61-
Namespace: item.Namespace,
62-
Name: item.ObjectMeta.Name,
63-
Paused: *item.Spec.Paused,
64-
DeferUpdates: *item.Spec.DeferUpdates,
65-
Kind: item.Spec.Kind,
66-
ImageConfig: item.Spec.PodTemplate.Options.ImageConfig,
67-
PodConfig: item.Spec.PodTemplate.Options.PodConfig,
68-
HomeVolume: *item.Spec.PodTemplate.Volumes.Home,
69-
DataVolumes: dataVolumes,
70-
Labels: item.ObjectMeta.Labels,
71-
Annotations: item.ObjectMeta.Annotations,
72-
Status: string(item.Status.State),
73-
LastActivity: formattedLastActivity,
74-
}
75-
return workspaceModel
76-
}

0 commit comments

Comments
 (0)