Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions workspaces/backend/api/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,17 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind {
VolumeMounts: kubefloworgv1beta1.WorkspaceKindVolumeMounts{
Home: "/home/jovyan",
},
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
RemovePathPrefix: ptr.To(false),
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
Set: map[string]string{"X-RStudio-Root-Path": "{{ .PathPrefix }}"},
Add: map[string]string{},
Remove: []string{},
Ports: []kubefloworgv1beta1.WorkspaceKindPort{
{
PortId: "jupyterlab",
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
RemovePathPrefix: ptr.To(false),
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
Set: map[string]string{},
Add: map[string]string{},
Remove: []string{},
},
},
},
},
ExtraEnv: []v1.EnvVar{
Expand Down
30 changes: 24 additions & 6 deletions workspaces/controller/api/v1beta1/workspacekind_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ import (
===============================================================================
*/

// PortId represents a port identifier
// - this is NOT used as the Container or Service port name, but as part of the HTTP path
// - this is used to reference the port in the `imageconfig` ports.[].id
// - this is also used to reference the port in the podtemplate ports.[].portId
//
Comment on lines +32 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// PortId represents a port identifier
// - this is NOT used as the Container or Service port name, but as part of the HTTP path
// - this is used to reference the port in the `imageconfig` ports.[].id
// - this is also used to reference the port in the podtemplate ports.[].portId
//
// PortId the id of the port

// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=32
// +kubebuilder:validation:Pattern:=^[a-z0-9][a-z0-9_-]*[a-z0-9]$
type PortId string

// WorkspaceKindSpec defines the desired state of WorkspaceKind
type WorkspaceKindSpec struct {

Expand Down Expand Up @@ -115,9 +125,9 @@ type WorkspaceKindPodTemplate struct {
// volume mount paths
VolumeMounts WorkspaceKindVolumeMounts `json:"volumeMounts"`

// http proxy configs (MUTABLE)
// ports that the container listens on
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// ports that the container listens on
// ports that the container listens on
// +listType:="map"
// +listMapKey:="id"

// +kubebuilder:validation:Optional
HTTPProxy *HTTPProxy `json:"httpProxy,omitempty"`
Ports []WorkspaceKindPort `json:"ports,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity - what is the practical purpose of defining a WorkspaceKind with no Ports ? Why would someone want to do that ?


// environment variables for Workspace Pods (MUTABLE)
// - the following go template functions are available:
Expand Down Expand Up @@ -151,6 +161,17 @@ type WorkspaceKindPodTemplate struct {
Options WorkspaceKindPodOptions `json:"options"`
}

type WorkspaceKindPort struct {
// the id of the port
// - identifier for the port in `imageconfig` ports.[].id
// +kubebuilder:example="jupyterlab"
PortId PortId `json:"portId"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably lets just make this id, because its kind of implied by the ports list.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all ports of the same ID should have the same protocol, we should remove the Protocol from imageConfigValue to here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a DefaultDisplayName field here, and make the one in imageConfigValue optional (pointer) so that people can override it for a specific image config option.

// the http proxy config for the port (MUTABLE)
// +kubebuilder:validation:Optional
HTTPProxy *HTTPProxy `json:"httpProxy,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity - what is the practical purpose of defining a PortId with no HTTProxy ? Is this moreso future-proofing as we anticipate other types of structs to be defined here in future (like SSH, etc)?

}

type WorkspaceKindPodMetadata struct {
// labels to be applied to the Pod resource
// +kubebuilder:validation:Optional
Expand Down Expand Up @@ -339,11 +360,8 @@ type ImageConfigSpec struct {
type ImagePort struct {
// the id of the port
// - this is NOT used as the Container or Service port name, but as part of the HTTP path
// +kubebuilder:validation:MinLength:=1
// +kubebuilder:validation:MaxLength:=32
// +kubebuilder:validation:Pattern:=^[a-z0-9][a-z0-9_-]*[a-z0-9]$
// +kubebuilder:example="jupyterlab"
Id string `json:"id"`
Id PortId `json:"id"`

// the port number
// +kubebuilder:validation:Minimum:=1
Expand Down
30 changes: 26 additions & 4 deletions workspaces/controller/api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2275,51 +2275,6 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
httpProxy:
description: http proxy configs (MUTABLE)
properties:
removePathPrefix:
default: false
description: |-
if the path prefix is stripped from incoming HTTP requests
- if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
is stripped from incoming requests, the application sees the request
as if it was made to '/...'
- this only works if the application serves RELATIVE URLs for its assets
type: boolean
requestHeaders:
description: |-
header manipulation rules for incoming HTTP requests
- sets the `spec.http[].headers.request` of the Istio VirtualService
https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
- the following string templates are available:
- `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
properties:
add:
additionalProperties:
type: string
description: append the given values to the headers specified
by keys (will create a comma-separated list of values)
example:
My-Header: value-to-append
type: object
remove:
description: remove the specified headers
example:
- Header-To-Remove
items:
type: string
type: array
set:
additionalProperties:
type: string
description: overwrite the headers specified by key with
the given values
example:
X-RStudio-Root-Path: '{{ .PathPrefix }}'
type: object
type: object
type: object
options:
description: options are the user-selectable fields, they determine
the PodSpec of the Workspace
Expand Down Expand Up @@ -3729,6 +3684,69 @@ spec:
description: labels to be applied to the Pod resource
type: object
type: object
ports:
description: ports that the container listens on
items:
properties:
httpProxy:
description: the http proxy config for the port (MUTABLE)
properties:
removePathPrefix:
default: false
description: |-
if the path prefix is stripped from incoming HTTP requests
- if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
is stripped from incoming requests, the application sees the request
as if it was made to '/...'
- this only works if the application serves RELATIVE URLs for its assets
type: boolean
requestHeaders:
description: |-
header manipulation rules for incoming HTTP requests
- sets the `spec.http[].headers.request` of the Istio VirtualService
https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
- the following string templates are available:
- `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
properties:
add:
additionalProperties:
type: string
description: append the given values to the headers
specified by keys (will create a comma-separated
list of values)
example:
My-Header: value-to-append
type: object
remove:
description: remove the specified headers
example:
- Header-To-Remove
items:
type: string
type: array
set:
additionalProperties:
type: string
description: overwrite the headers specified by
key with the given values
example:
X-RStudio-Root-Path: '{{ .PathPrefix }}'
type: object
type: object
type: object
portId:
description: |-
the id of the port
- identifier for the port in `imageconfig` ports.[].id
example: jupyterlab
maxLength: 32
minLength: 1
pattern: ^[a-z0-9][a-z0-9_-]*[a-z0-9]$
type: string
required:
- portId
type: object
type: array
probes:
description: standard probes to determine Container health (MUTABLE)
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,28 +135,36 @@ spec:
##
home: "/home/jovyan"

## http proxy configs (MUTABLE)
##
httpProxy:

## if the path prefix is stripped from incoming HTTP requests
## - if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
## is stripped from incoming requests, the application sees the request
## as if it was made to '/...'
## - this only works if the application serves RELATIVE URLs for its assets
##
removePathPrefix: false
## port configs (MUTABLE)
ports:

## the list of ports that the Workspace exposes
## configs apply to a single port
## portId is the identifier for the port in `imageconfig` ports.[].id
- portId: "jupyterlab"

## http proxy configs (MUTABLE)
## only "HTTP" protocol ports are supported
httpProxy:

## if the path prefix is stripped from incoming HTTP requests
## - if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
## is stripped from incoming requests, the application sees the request
## as if it was made to '/...'
## - this only works if the application serves RELATIVE URLs for its assets
##
removePathPrefix: false

## header manipulation rules for incoming HTTP requests
## - sets the `spec.http[].headers.request` of the Istio VirtualService
## https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
## - the following string templates are available:
## - `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
##
requestHeaders: {}
#set: { "X-RStudio-Root-Path": "{{ .PathPrefix }}" } # for RStudio
#add: {}
#remove: []
## header manipulation rules for incoming HTTP requests
## - sets the `spec.http[].headers.request` of the Istio VirtualService
## https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
## - the following string templates are available:
## - `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
##
requestHeaders: {}
#set: { "X-RStudio-Root-Path": "{{ .PathPrefix }}" } # for RStudio
#add: {}
#remove: []

## environment variables for Workspace Pods (MUTABLE)
## - spec for EnvVar:
Expand Down
17 changes: 11 additions & 6 deletions workspaces/controller/internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,17 @@ func NewExampleWorkspaceKind1(name string) *kubefloworgv1beta1.WorkspaceKind {
VolumeMounts: kubefloworgv1beta1.WorkspaceKindVolumeMounts{
Home: "/home/jovyan",
},
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
RemovePathPrefix: ptr.To(false),
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
Set: map[string]string{"X-RStudio-Root-Path": "{{ .PathPrefix }}"},
Add: map[string]string{},
Remove: []string{},
Ports: []kubefloworgv1beta1.WorkspaceKindPort{
{
PortId: "jupyterlab",
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
RemovePathPrefix: ptr.To(false),
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
Set: map[string]string{},
Add: map[string]string{},
Remove: []string{},
},
},
},
},
ExtraEnv: []v1.EnvVar{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ func generateStatefulSet(workspace *kubefloworgv1beta1.Workspace, workspaceKind
seenPorts[port.Port] = true

// NOTE: we construct this map for use in the go string templates
containerPortsIdMap[port.Id] = port
containerPortsIdMap[string(port.Id)] = port
}

// generate container env
Expand Down
Loading