feat(ws): add ws counts to backend wsk model (#368)
Signed-off-by: rafriat <roee.afriat.ext@nokia.com> Co-authored-by: rafriat <roee.afriat.ext@nokia.com>
This commit is contained in:
parent
f3fc2e200d
commit
0db1fd7c72
|
|
@ -455,5 +455,34 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Status: kubefloworgv1beta1.WorkspaceKindStatus{
|
||||||
|
Workspaces: 1,
|
||||||
|
PodTemplateOptions: kubefloworgv1beta1.PodTemplateOptionsMetrics{
|
||||||
|
ImageConfig: []kubefloworgv1beta1.OptionMetric{
|
||||||
|
{
|
||||||
|
Id: "jupyterlab_scipy_180",
|
||||||
|
Workspaces: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "jupyterlab_scipy_190",
|
||||||
|
Workspaces: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
PodConfig: []kubefloworgv1beta1.OptionMetric{
|
||||||
|
{
|
||||||
|
Id: "tiny_cpu",
|
||||||
|
Workspaces: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "small_cpu",
|
||||||
|
Workspaces: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id: "big_gpu",
|
||||||
|
Workspaces: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ func NewWorkspaceKindModelFromWorkspaceKind(wsk *kubefloworgv1beta1.WorkspaceKin
|
||||||
podAnnotations[k] = v
|
podAnnotations[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
statusImageConfigMap := buildOptionMetricsMap(wsk.Status.PodTemplateOptions.ImageConfig)
|
||||||
|
statusPodConfigMap := buildOptionMetricsMap(wsk.Status.PodTemplateOptions.PodConfig)
|
||||||
|
|
||||||
// TODO: icons can either be a remote URL or read from a ConfigMap.
|
// TODO: icons can either be a remote URL or read from a ConfigMap.
|
||||||
// in BOTH cases, we should cache and serve the image under a path on the backend API:
|
// in BOTH cases, we should cache and serve the image under a path on the backend API:
|
||||||
|
|
@ -60,6 +62,10 @@ func NewWorkspaceKindModelFromWorkspaceKind(wsk *kubefloworgv1beta1.WorkspaceKin
|
||||||
Hidden: ptr.Deref(wsk.Spec.Spawner.Hidden, false),
|
Hidden: ptr.Deref(wsk.Spec.Spawner.Hidden, false),
|
||||||
Icon: iconRef,
|
Icon: iconRef,
|
||||||
Logo: logoRef,
|
Logo: logoRef,
|
||||||
|
// TODO: in the future will need to support including exactly one of clusterMetrics or namespaceMetrics based on request context
|
||||||
|
ClusterMetrics: clusterMetrics{
|
||||||
|
Workspaces: wsk.Status.Workspaces,
|
||||||
|
},
|
||||||
PodTemplate: PodTemplate{
|
PodTemplate: PodTemplate{
|
||||||
PodMetadata: PodMetadata{
|
PodMetadata: PodMetadata{
|
||||||
Labels: podLabels,
|
Labels: podLabels,
|
||||||
|
|
@ -71,18 +77,26 @@ func NewWorkspaceKindModelFromWorkspaceKind(wsk *kubefloworgv1beta1.WorkspaceKin
|
||||||
Options: PodTemplateOptions{
|
Options: PodTemplateOptions{
|
||||||
ImageConfig: ImageConfig{
|
ImageConfig: ImageConfig{
|
||||||
Default: wsk.Spec.PodTemplate.Options.ImageConfig.Spawner.Default,
|
Default: wsk.Spec.PodTemplate.Options.ImageConfig.Spawner.Default,
|
||||||
Values: buildImageConfigValues(wsk.Spec.PodTemplate.Options.ImageConfig),
|
Values: buildImageConfigValues(wsk.Spec.PodTemplate.Options.ImageConfig, statusImageConfigMap),
|
||||||
},
|
},
|
||||||
PodConfig: PodConfig{
|
PodConfig: PodConfig{
|
||||||
Default: wsk.Spec.PodTemplate.Options.PodConfig.Spawner.Default,
|
Default: wsk.Spec.PodTemplate.Options.PodConfig.Spawner.Default,
|
||||||
Values: buildPodConfigValues(wsk.Spec.PodTemplate.Options.PodConfig),
|
Values: buildPodConfigValues(wsk.Spec.PodTemplate.Options.PodConfig, statusPodConfigMap),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildImageConfigValues(imageConfig kubefloworgv1beta1.ImageConfig) []ImageConfigValue {
|
func buildOptionMetricsMap(metrics []kubefloworgv1beta1.OptionMetric) map[string]int32 {
|
||||||
|
resultMap := make(map[string]int32)
|
||||||
|
for _, metric := range metrics {
|
||||||
|
resultMap[metric.Id] = metric.Workspaces
|
||||||
|
}
|
||||||
|
return resultMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildImageConfigValues(imageConfig kubefloworgv1beta1.ImageConfig, statusImageConfigMap map[string]int32) []ImageConfigValue {
|
||||||
imageConfigValues := make([]ImageConfigValue, len(imageConfig.Values))
|
imageConfigValues := make([]ImageConfigValue, len(imageConfig.Values))
|
||||||
for i := range imageConfig.Values {
|
for i := range imageConfig.Values {
|
||||||
option := imageConfig.Values[i]
|
option := imageConfig.Values[i]
|
||||||
|
|
@ -93,12 +107,16 @@ func buildImageConfigValues(imageConfig kubefloworgv1beta1.ImageConfig) []ImageC
|
||||||
Labels: buildOptionLabels(option.Spawner.Labels),
|
Labels: buildOptionLabels(option.Spawner.Labels),
|
||||||
Hidden: ptr.Deref(option.Spawner.Hidden, false),
|
Hidden: ptr.Deref(option.Spawner.Hidden, false),
|
||||||
Redirect: buildOptionRedirect(option.Redirect),
|
Redirect: buildOptionRedirect(option.Redirect),
|
||||||
|
// TODO: in the future will need to support including exactly one of clusterMetrics or namespaceMetrics based on request context
|
||||||
|
ClusterMetrics: clusterMetrics{
|
||||||
|
Workspaces: statusImageConfigMap[option.Id],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return imageConfigValues
|
return imageConfigValues
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildPodConfigValues(podConfig kubefloworgv1beta1.PodConfig) []PodConfigValue {
|
func buildPodConfigValues(podConfig kubefloworgv1beta1.PodConfig, statusPodConfigMap map[string]int32) []PodConfigValue {
|
||||||
podConfigValues := make([]PodConfigValue, len(podConfig.Values))
|
podConfigValues := make([]PodConfigValue, len(podConfig.Values))
|
||||||
for i := range podConfig.Values {
|
for i := range podConfig.Values {
|
||||||
option := podConfig.Values[i]
|
option := podConfig.Values[i]
|
||||||
|
|
@ -109,6 +127,10 @@ func buildPodConfigValues(podConfig kubefloworgv1beta1.PodConfig) []PodConfigVal
|
||||||
Labels: buildOptionLabels(option.Spawner.Labels),
|
Labels: buildOptionLabels(option.Spawner.Labels),
|
||||||
Hidden: ptr.Deref(option.Spawner.Hidden, false),
|
Hidden: ptr.Deref(option.Spawner.Hidden, false),
|
||||||
Redirect: buildOptionRedirect(option.Redirect),
|
Redirect: buildOptionRedirect(option.Redirect),
|
||||||
|
// TODO: in the future will need to support including exactly one of clusterMetrics or namespaceMetrics based on request context
|
||||||
|
ClusterMetrics: clusterMetrics{
|
||||||
|
Workspaces: statusPodConfigMap[option.Id],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return podConfigValues
|
return podConfigValues
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,20 @@ limitations under the License.
|
||||||
package workspacekinds
|
package workspacekinds
|
||||||
|
|
||||||
type WorkspaceKind struct {
|
type WorkspaceKind struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Deprecated bool `json:"deprecated"`
|
Deprecated bool `json:"deprecated"`
|
||||||
DeprecationMessage string `json:"deprecationMessage"`
|
DeprecationMessage string `json:"deprecationMessage"`
|
||||||
Hidden bool `json:"hidden"`
|
Hidden bool `json:"hidden"`
|
||||||
Icon ImageRef `json:"icon"`
|
Icon ImageRef `json:"icon"`
|
||||||
Logo ImageRef `json:"logo"`
|
Logo ImageRef `json:"logo"`
|
||||||
PodTemplate PodTemplate `json:"podTemplate"`
|
ClusterMetrics clusterMetrics `json:"clusterMetrics,omitempty"`
|
||||||
|
PodTemplate PodTemplate `json:"podTemplate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type clusterMetrics struct {
|
||||||
|
Workspaces int32 `json:"workspacesCount"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageRef struct {
|
type ImageRef struct {
|
||||||
|
|
@ -58,12 +63,13 @@ type ImageConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageConfigValue struct {
|
type ImageConfigValue struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Labels []OptionLabel `json:"labels"`
|
Labels []OptionLabel `json:"labels"`
|
||||||
Hidden bool `json:"hidden"`
|
Hidden bool `json:"hidden"`
|
||||||
Redirect *OptionRedirect `json:"redirect,omitempty"`
|
Redirect *OptionRedirect `json:"redirect,omitempty"`
|
||||||
|
ClusterMetrics clusterMetrics `json:"clusterMetrics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PodConfig struct {
|
type PodConfig struct {
|
||||||
|
|
@ -72,12 +78,13 @@ type PodConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PodConfigValue struct {
|
type PodConfigValue struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Labels []OptionLabel `json:"labels"`
|
Labels []OptionLabel `json:"labels"`
|
||||||
Hidden bool `json:"hidden"`
|
Hidden bool `json:"hidden"`
|
||||||
Redirect *OptionRedirect `json:"redirect,omitempty"`
|
Redirect *OptionRedirect `json:"redirect,omitempty"`
|
||||||
|
ClusterMetrics clusterMetrics `json:"clusterMetrics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionLabel struct {
|
type OptionLabel struct {
|
||||||
|
|
|
||||||
|
|
@ -778,6 +778,9 @@ const docTemplate = `{
|
||||||
"workspacekinds.ImageConfigValue": {
|
"workspacekinds.ImageConfigValue": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
@ -848,6 +851,9 @@ const docTemplate = `{
|
||||||
"workspacekinds.PodConfigValue": {
|
"workspacekinds.PodConfigValue": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
@ -948,6 +954,9 @@ const docTemplate = `{
|
||||||
"workspacekinds.WorkspaceKind": {
|
"workspacekinds.WorkspaceKind": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"deprecated": {
|
"deprecated": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
|
@ -977,6 +986,14 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"workspacekinds.clusterMetrics": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspacesCount": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"workspaces.Activity": {
|
"workspaces.Activity": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -776,6 +776,9 @@
|
||||||
"workspacekinds.ImageConfigValue": {
|
"workspacekinds.ImageConfigValue": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
@ -846,6 +849,9 @@
|
||||||
"workspacekinds.PodConfigValue": {
|
"workspacekinds.PodConfigValue": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
@ -946,6 +952,9 @@
|
||||||
"workspacekinds.WorkspaceKind": {
|
"workspacekinds.WorkspaceKind": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"clusterMetrics": {
|
||||||
|
"$ref": "#/definitions/workspacekinds.clusterMetrics"
|
||||||
|
},
|
||||||
"deprecated": {
|
"deprecated": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
|
@ -975,6 +984,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"workspacekinds.clusterMetrics": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"workspacesCount": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"workspaces.Activity": {
|
"workspaces.Activity": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue