Skip to content

Commit 438e485

Browse files
committed
include ports array in podtemplate for httpProxy setting
- add validation webhook for podtemplate.ports Signed-off-by: Harshad Reddy Nalla <[email protected]>
1 parent 03c14dd commit 438e485

File tree

9 files changed

+300
-90
lines changed

9 files changed

+300
-90
lines changed

workspaces/backend/api/suite_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,17 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind {
245245
VolumeMounts: kubefloworgv1beta1.WorkspaceKindVolumeMounts{
246246
Home: "/home/jovyan",
247247
},
248-
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
249-
RemovePathPrefix: ptr.To(false),
250-
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
251-
Set: map[string]string{"X-RStudio-Root-Path": "{{ .PathPrefix }}"},
252-
Add: map[string]string{},
253-
Remove: []string{},
248+
Ports: []kubefloworgv1beta1.WorkspaceKindPort{
249+
{
250+
PortId: "jupyterlab",
251+
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
252+
RemovePathPrefix: ptr.To(false),
253+
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
254+
Set: map[string]string{},
255+
Add: map[string]string{},
256+
Remove: []string{},
257+
},
258+
},
254259
},
255260
},
256261
ExtraEnv: []v1.EnvVar{

workspaces/controller/api/v1beta1/workspacekind_types.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ type WorkspaceKindPodTemplate struct {
115115
// volume mount paths
116116
VolumeMounts WorkspaceKindVolumeMounts `json:"volumeMounts"`
117117

118-
// http proxy configs (MUTABLE)
118+
// ports that the container listens on
119119
// +kubebuilder:validation:Optional
120-
HTTPProxy *HTTPProxy `json:"httpProxy,omitempty"`
120+
Ports []WorkspaceKindPort `json:"ports,omitempty"`
121121

122122
// environment variables for Workspace Pods (MUTABLE)
123123
// - the following go template functions are available:
@@ -151,6 +151,20 @@ type WorkspaceKindPodTemplate struct {
151151
Options WorkspaceKindPodOptions `json:"options"`
152152
}
153153

154+
type WorkspaceKindPort struct {
155+
// the id of the port
156+
// - identifier for the port in `imageconfig` ports.[].id
157+
// +kubebuilder:validation:MinLength:=1
158+
// +kubebuilder:validation:MaxLength:=32
159+
// +kubebuilder:validation:Pattern:=^[a-z0-9][a-z0-9_-]*[a-z0-9]$
160+
// +kubebuilder:example="jupyterlab"
161+
PortId string `json:"portId"`
162+
163+
// the http proxy config for the port (MUTABLE)
164+
// +kubebuilder:validation:Optional
165+
HTTPProxy *HTTPProxy `json:"httpProxy,omitempty"`
166+
}
167+
154168
type WorkspaceKindPodMetadata struct {
155169
// labels to be applied to the Pod resource
156170
// +kubebuilder:validation:Optional

workspaces/controller/api/v1beta1/zz_generated.deepcopy.go

Lines changed: 26 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

workspaces/controller/config/crd/bases/kubeflow.org_workspacekinds.yaml

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,51 +2275,6 @@ spec:
22752275
x-kubernetes-list-map-keys:
22762276
- name
22772277
x-kubernetes-list-type: map
2278-
httpProxy:
2279-
description: http proxy configs (MUTABLE)
2280-
properties:
2281-
removePathPrefix:
2282-
default: false
2283-
description: |-
2284-
if the path prefix is stripped from incoming HTTP requests
2285-
- if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
2286-
is stripped from incoming requests, the application sees the request
2287-
as if it was made to '/...'
2288-
- this only works if the application serves RELATIVE URLs for its assets
2289-
type: boolean
2290-
requestHeaders:
2291-
description: |-
2292-
header manipulation rules for incoming HTTP requests
2293-
- sets the `spec.http[].headers.request` of the Istio VirtualService
2294-
https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
2295-
- the following string templates are available:
2296-
- `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
2297-
properties:
2298-
add:
2299-
additionalProperties:
2300-
type: string
2301-
description: append the given values to the headers specified
2302-
by keys (will create a comma-separated list of values)
2303-
example:
2304-
My-Header: value-to-append
2305-
type: object
2306-
remove:
2307-
description: remove the specified headers
2308-
example:
2309-
- Header-To-Remove
2310-
items:
2311-
type: string
2312-
type: array
2313-
set:
2314-
additionalProperties:
2315-
type: string
2316-
description: overwrite the headers specified by key with
2317-
the given values
2318-
example:
2319-
X-RStudio-Root-Path: '{{ .PathPrefix }}'
2320-
type: object
2321-
type: object
2322-
type: object
23232278
options:
23242279
description: options are the user-selectable fields, they determine
23252280
the PodSpec of the Workspace
@@ -3729,6 +3684,69 @@ spec:
37293684
description: labels to be applied to the Pod resource
37303685
type: object
37313686
type: object
3687+
ports:
3688+
description: ports that the container listens on
3689+
items:
3690+
properties:
3691+
httpProxy:
3692+
description: the http proxy config for the port (MUTABLE)
3693+
properties:
3694+
removePathPrefix:
3695+
default: false
3696+
description: |-
3697+
if the path prefix is stripped from incoming HTTP requests
3698+
- if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
3699+
is stripped from incoming requests, the application sees the request
3700+
as if it was made to '/...'
3701+
- this only works if the application serves RELATIVE URLs for its assets
3702+
type: boolean
3703+
requestHeaders:
3704+
description: |-
3705+
header manipulation rules for incoming HTTP requests
3706+
- sets the `spec.http[].headers.request` of the Istio VirtualService
3707+
https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
3708+
- the following string templates are available:
3709+
- `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
3710+
properties:
3711+
add:
3712+
additionalProperties:
3713+
type: string
3714+
description: append the given values to the headers
3715+
specified by keys (will create a comma-separated
3716+
list of values)
3717+
example:
3718+
My-Header: value-to-append
3719+
type: object
3720+
remove:
3721+
description: remove the specified headers
3722+
example:
3723+
- Header-To-Remove
3724+
items:
3725+
type: string
3726+
type: array
3727+
set:
3728+
additionalProperties:
3729+
type: string
3730+
description: overwrite the headers specified by
3731+
key with the given values
3732+
example:
3733+
X-RStudio-Root-Path: '{{ .PathPrefix }}'
3734+
type: object
3735+
type: object
3736+
type: object
3737+
portId:
3738+
description: |-
3739+
the id of the port
3740+
- identifier for the port in `imageconfig` ports.[].id
3741+
example: jupyterlab
3742+
maxLength: 32
3743+
minLength: 1
3744+
pattern: ^[a-z0-9][a-z0-9_-]*[a-z0-9]$
3745+
type: string
3746+
required:
3747+
- portId
3748+
type: object
3749+
type: array
37323750
probes:
37333751
description: standard probes to determine Container health (MUTABLE)
37343752
properties:

workspaces/controller/config/samples/jupyterlab_v1beta1_workspacekind.yaml

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -135,28 +135,36 @@ spec:
135135
##
136136
home: "/home/jovyan"
137137

138-
## http proxy configs (MUTABLE)
139-
##
140-
httpProxy:
141-
142-
## if the path prefix is stripped from incoming HTTP requests
143-
## - if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
144-
## is stripped from incoming requests, the application sees the request
145-
## as if it was made to '/...'
146-
## - this only works if the application serves RELATIVE URLs for its assets
147-
##
148-
removePathPrefix: false
138+
## port configs (MUTABLE)
139+
ports:
140+
141+
## the list of ports that the Workspace exposes
142+
## configs apply to a single port
143+
## portId is the identifier for the port in `imageconfig` ports.[].id
144+
- portid: "jupyterlab"
145+
146+
## http proxy configs (MUTABLE)
147+
## only "HTTP" protocol ports are supported
148+
httpProxy:
149+
150+
## if the path prefix is stripped from incoming HTTP requests
151+
## - if true, the '/workspace/{profile_name}/{workspace_name}/' path prefix
152+
## is stripped from incoming requests, the application sees the request
153+
## as if it was made to '/...'
154+
## - this only works if the application serves RELATIVE URLs for its assets
155+
##
156+
removePathPrefix: false
149157

150-
## header manipulation rules for incoming HTTP requests
151-
## - sets the `spec.http[].headers.request` of the Istio VirtualService
152-
## https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
153-
## - the following string templates are available:
154-
## - `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
155-
##
156-
requestHeaders: {}
157-
#set: { "X-RStudio-Root-Path": "{{ .PathPrefix }}" } # for RStudio
158-
#add: {}
159-
#remove: []
158+
## header manipulation rules for incoming HTTP requests
159+
## - sets the `spec.http[].headers.request` of the Istio VirtualService
160+
## https://istio.io/latest/docs/reference/config/networking/virtual-service/#Headers-HeaderOperations
161+
## - the following string templates are available:
162+
## - `.PathPrefix`: the path prefix of the Workspace (e.g. '/workspace/{profile_name}/{workspace_name}/')
163+
##
164+
requestHeaders: {}
165+
#set: { "X-RStudio-Root-Path": "{{ .PathPrefix }}" } # for RStudio
166+
#add: {}
167+
#remove: []
160168

161169
## environment variables for Workspace Pods (MUTABLE)
162170
## - spec for EnvVar:

workspaces/controller/internal/controller/suite_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,17 @@ func NewExampleWorkspaceKind1(name string) *kubefloworgv1beta1.WorkspaceKind {
220220
VolumeMounts: kubefloworgv1beta1.WorkspaceKindVolumeMounts{
221221
Home: "/home/jovyan",
222222
},
223-
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
224-
RemovePathPrefix: ptr.To(false),
225-
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
226-
Set: map[string]string{"X-RStudio-Root-Path": "{{ .PathPrefix }}"},
227-
Add: map[string]string{},
228-
Remove: []string{},
223+
Ports: []kubefloworgv1beta1.WorkspaceKindPort{
224+
{
225+
PortId: "jupyterlab",
226+
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
227+
RemovePathPrefix: ptr.To(false),
228+
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
229+
Set: map[string]string{},
230+
Add: map[string]string{},
231+
Remove: []string{},
232+
},
233+
},
229234
},
230235
},
231236
ExtraEnv: []v1.EnvVar{

workspaces/controller/internal/webhook/suite_test.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,20 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind {
208208
VolumeMounts: kubefloworgv1beta1.WorkspaceKindVolumeMounts{
209209
Home: "/home/jovyan",
210210
},
211-
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
212-
RemovePathPrefix: ptr.To(false),
213-
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
214-
Set: map[string]string{"X-RStudio-Root-Path": "{{ .PathPrefix }}"},
215-
Add: map[string]string{},
216-
Remove: []string{},
211+
Ports: []kubefloworgv1beta1.WorkspaceKindPort{
212+
{
213+
PortId: "jupyterlab",
214+
HTTPProxy: &kubefloworgv1beta1.HTTPProxy{
215+
RemovePathPrefix: ptr.To(false),
216+
RequestHeaders: &kubefloworgv1beta1.IstioHeaderOperations{
217+
Set: map[string]string{},
218+
Add: map[string]string{},
219+
Remove: []string{},
220+
},
221+
},
222+
},
223+
{
224+
PortId: "my_port",
217225
},
218226
},
219227
ExtraEnv: []v1.EnvVar{
@@ -613,6 +621,38 @@ func NewExampleWorkspaceKindWithDuplicatePorts(name string) *kubefloworgv1beta1.
613621
return workspaceKind
614622
}
615623

624+
// NewExampleWorkspaceKindWithEmptyPortsArrayInPodTemplate returns a WorkspaceKind with an empty ports array in podTemplate.ports.
625+
func NewExampleWorkspaceKindWithEmptyPortsArrayInPodTemplate(name string) *kubefloworgv1beta1.WorkspaceKind {
626+
workspaceKind := NewExampleWorkspaceKind(name)
627+
workspaceKind.Spec.PodTemplate.Ports = []kubefloworgv1beta1.WorkspaceKindPort{}
628+
return workspaceKind
629+
}
630+
631+
// NewExampleWorkspaceKindWithDuplicatePortsInPodTemplate returns a WorkspaceKind with duplicate ports in podTemplate.ports.
632+
func NewExampleWorkspaceKindWithDuplicatePortsInPodTemplate(name string) *kubefloworgv1beta1.WorkspaceKind {
633+
workspaceKind := NewExampleWorkspaceKind(name)
634+
workspaceKind.Spec.PodTemplate.Ports = []kubefloworgv1beta1.WorkspaceKindPort{
635+
{
636+
PortId: "jupyterlab",
637+
},
638+
{
639+
PortId: "jupyterlab",
640+
},
641+
}
642+
return workspaceKind
643+
}
644+
645+
// NewExampleWorkspaceKindWithNonExistentPortIdInImageConfig returns a WorkspaceKind with a non-existent portId in imageConfig.ports.
646+
func NewExampleWorkspaceKindWithNonExistentPortIdInImageConfig(name string) *kubefloworgv1beta1.WorkspaceKind {
647+
workspaceKind := NewExampleWorkspaceKind(name)
648+
workspaceKind.Spec.PodTemplate.Ports = []kubefloworgv1beta1.WorkspaceKindPort{
649+
{
650+
PortId: "non-existent-port-id",
651+
},
652+
}
653+
return workspaceKind
654+
}
655+
616656
// NewExampleWorkspaceKindWithInvalidExtraEnvValue returns a WorkspaceKind with an invalid extraEnv value.
617657
func NewExampleWorkspaceKindWithInvalidExtraEnvValue(name string) *kubefloworgv1beta1.WorkspaceKind {
618658
workspaceKind := NewExampleWorkspaceKind(name)

0 commit comments

Comments
 (0)