Skip to content

Commit bb76efb

Browse files
committed
test(workbenches): update existing workbench tests for RHOAI 3.0
With RHOAI 3.0 release, there were quite number of changes needed for our tests as we moved from OAuth Proxy sidecar container to a Kube RBAC Proxy. Also we moved to the Gateway API. All tracked under the https://issues.redhat.com/browse/RHOAIENG-34310
1 parent 44ba691 commit bb76efb

File tree

3 files changed

+97
-78
lines changed

3 files changed

+97
-78
lines changed

tests/workbenches/conftest.py

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Generator
22

3+
from ocp_resources.resource import NamespacedResource
34
import pytest
45
from pytest_testconfig import config as py_config
56

@@ -11,7 +12,7 @@
1112

1213
from ocp_resources.namespace import Namespace
1314
from ocp_resources.persistent_volume_claim import PersistentVolumeClaim
14-
from ocp_resources.route import Route
15+
from ocp_resources.gateway_gateway_networking_k8s_io import Gateway
1516
from ocp_resources.notebook import Notebook
1617

1718
from utilities.constants import Labels
@@ -55,14 +56,23 @@ def default_notebook(
5556
namespace = request.param["namespace"]
5657
name = request.param["name"]
5758

58-
# Optional OAuth annotations
59-
oauth_annotations = request.param.get("oauth_annotations", {})
59+
# Optional Auth annotations
60+
auth_annotations = request.param.get("auth_annotations", {})
6061

61-
# Set new Route url
62-
route_name = "odh-dashboard" if py_config.get("distribution") == "upstream" else "rhods-dashboard"
63-
route = Route(client=admin_client, name=route_name, namespace=py_config["applications_namespace"])
64-
if not route.exists:
65-
raise ResourceNotFoundError(f"Route {route.name} does not exist")
62+
# Get hostname from Gateway CR
63+
gateway = Gateway(
64+
client=admin_client,
65+
name="data-science-gateway",
66+
namespace="openshift-ingress"
67+
)
68+
if not gateway.exists:
69+
raise ResourceNotFoundError(f"Gateway {gateway.name} does not exist in namespace {gateway.namespace}")
70+
71+
# Extract hostname from the first listener
72+
try:
73+
hostname = gateway.instance.spec.listeners[0].hostname
74+
except (KeyError, IndexError, AttributeError) as e:
75+
raise ResourceNotFoundError(f"Failed to get hostname from Gateway {gateway.name}: {e}")
6676

6777
# Set the correct username
6878
username = get_username(dyn_client=admin_client)
@@ -96,18 +106,19 @@ def default_notebook(
96106
"kind": "Notebook",
97107
"metadata": {
98108
"annotations": {
99-
"notebooks.opendatahub.io/inject-oauth": "true",
109+
Labels.Notebook.INJECT_AUTH: "true",
100110
"opendatahub.io/accelerator-name": "",
101-
"opendatahub.io/service-mesh": "false",
102111
"notebooks.opendatahub.io/last-image-selection": minimal_image,
103112
# Add any additional annotations if provided
104-
**oauth_annotations,
113+
**auth_annotations,
105114
},
115+
"finalizers": [
116+
"notebook.opendatahub.io/kube-rbac-proxy-cleanup",
117+
],
106118
"labels": {
107119
Labels.Openshift.APP: name,
108120
Labels.OpenDataHub.DASHBOARD: "true",
109121
"opendatahub.io/odh-managed": "true",
110-
"sidecar.istio.io/inject": "false",
111122
},
112123
"name": name,
113124
"namespace": namespace,
@@ -129,9 +140,7 @@ def default_notebook(
129140
" "
130141
f"--ServerApp.base_url=/notebook/{namespace}/{name}\n"
131142
" "
132-
"--ServerApp.quit_button=False\n"
133-
" "
134-
f'--ServerApp.tornado_settings={{"user":"{username}","hub_host":"https://{route.host}","hub_prefix":"/projects/{namespace}"}}', # noqa: E501 line too long
143+
"--ServerApp.quit_button=False\n",
135144
},
136145
{"name": "JUPYTER_IMAGE", "value": minimal_image_path},
137146
],
@@ -152,52 +161,48 @@ def default_notebook(
152161
"workingDir": "/opt/app-root/src",
153162
},
154163
{
155-
"args": [
156-
"--provider=openshift",
157-
"--https-address=:8443",
158-
"--http-address=",
159-
f"--openshift-service-account={name}",
160-
"--cookie-secret-file=/etc/oauth/config/cookie_secret",
161-
"--cookie-expire=24h0m0s",
162-
"--tls-cert=/etc/tls/private/tls.crt",
163-
"--tls-key=/etc/tls/private/tls.key",
164-
"--upstream=http://localhost:8888",
165-
"--upstream-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt",
166-
"--email-domain=*",
167-
"--skip-provider-button",
168-
f'--openshift-sar={{"verb":"get","resource":"notebooks","resourceAPIGroup":"kubeflow.org","resourceName":"{name}","namespace":"$(NAMESPACE)"}}', # noqa: E501 line too long
169-
f"--logout-url=https://{route.host}/projects/{namespace}?notebookLogout={name}",
170-
],
171-
"env": [
172-
{"name": "NAMESPACE", "valueFrom": {"fieldRef": {"fieldPath": "metadata.namespace"}}}
173-
],
174-
"image": "registry.redhat.io/openshift4/ose-oauth-proxy:v4.10",
175-
"imagePullPolicy": "Always",
176-
"livenessProbe": {
164+
"resources": {
165+
"limits": {"cpu": "100m", "memory": "64Mi"},
166+
"requests": {"cpu": "100m", "memory": "64Mi"},
167+
},
168+
"readinessProbe": {
177169
"failureThreshold": 3,
178-
"httpGet": {"path": "/oauth/healthz", "port": "oauth-proxy", "scheme": "HTTPS"},
179-
"initialDelaySeconds": 30,
170+
"httpGet": {"path": "/healthz", "port": 8444, "scheme": "HTTPS"},
171+
"initialDelaySeconds": 5,
180172
"periodSeconds": 5,
181173
"successThreshold": 1,
182174
"timeoutSeconds": 1,
183175
},
184-
"name": "oauth-proxy",
185-
"ports": [{"containerPort": 8443, "name": "oauth-proxy", "protocol": "TCP"}],
186-
"readinessProbe": {
176+
"name": "kube-rbac-proxy",
177+
"livenessProbe": {
187178
"failureThreshold": 3,
188-
"httpGet": {"path": "/oauth/healthz", "port": "oauth-proxy", "scheme": "HTTPS"},
189-
"initialDelaySeconds": 5,
179+
"httpGet": {"path": "/healthz", "port": 8444, "scheme": "HTTPS"},
180+
"initialDelaySeconds": 30,
190181
"periodSeconds": 5,
191182
"successThreshold": 1,
192183
"timeoutSeconds": 1,
193184
},
194-
"resources": {
195-
"limits": {"cpu": "100m", "memory": "64Mi"},
196-
"requests": {"cpu": "100m", "memory": "64Mi"},
197-
},
185+
"ports": [
186+
{"containerPort": 8443, "name": "kube-rbac-proxy", "protocol": "TCP"}
187+
],
188+
"imagePullPolicy": "Always",
198189
"volumeMounts": [
199-
{"mountPath": "/etc/oauth/config", "name": "oauth-config"},
200-
{"mountPath": "/etc/tls/private", "name": "tls-certificates"},
190+
{"mountPath": "/etc/kube-rbac-proxy", "name": "kube-rbac-proxy-config"},
191+
{"mountPath": "/etc/tls/private", "name": "kube-rbac-proxy-tls-certificates"},
192+
],
193+
"image": "registry.redhat.io/rhoai/odh-kube-auth-proxy-rhel9@sha256:e4047ff1041a8b1efd21110751d0f87520d5483a7e26c35844f5d8d165de8177",
194+
"args": [
195+
"--secure-listen-address=0.0.0.0:8443",
196+
"--upstream=http://127.0.0.1:8888/",
197+
"--logtostderr=true",
198+
"--v=10",
199+
"--proxy-endpoints-port=8444",
200+
"--config-file=/etc/kube-rbac-proxy/config-file.yaml",
201+
"--tls-cert-file=/etc/tls/private/tls.crt",
202+
"--tls-private-key-file=/etc/tls/private/tls.key",
203+
"--auth-header-fields-enabled=true",
204+
"--auth-header-user-field-name=X-Auth-Request-User",
205+
"--auth-header-groups-field-name=X-Auth-Request-Groups",
201206
],
202207
},
203208
],
@@ -206,11 +211,25 @@ def default_notebook(
206211
"volumes": [
207212
{"name": name, "persistentVolumeClaim": {"claimName": name}},
208213
{"emptyDir": {"medium": "Memory"}, "name": "shm"},
214+
# {
215+
# "name": "oauth-config",
216+
# "secret": {"defaultMode": 420, "secretName": f"{name}-oauth-config"},
217+
# },
218+
# {"name": "tls-certificates", "secret": {"defaultMode": 420, "secretName": f"{name}-tls"}},
209219
{
210-
"name": "oauth-config",
211-
"secret": {"defaultMode": 420, "secretName": f"{name}-oauth-config"},
220+
"name": "kube-rbac-proxy-config",
221+
"configMap": {
222+
"defaultMode": 420,
223+
"name": "test-kube-rbac-proxy-config"
224+
}
212225
},
213-
{"name": "tls-certificates", "secret": {"defaultMode": 420, "secretName": f"{name}-tls"}},
226+
{
227+
"name": "kube-rbac-proxy-tls-certificates",
228+
"secret": {
229+
"defaultMode": 420,
230+
"secretName": "test-kube-rbac-proxy-tls"
231+
}
232+
}
214233
],
215234
}
216235
}

tests/workbenches/notebook-controller/test_spawning.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ def test_create_simple_notebook(
5151
[
5252
pytest.param(
5353
{
54-
"name": "test-oauth-notebook",
54+
"name": "test-auth-notebook",
5555
"add-dashboard-label": True,
5656
},
57-
{"name": "test-oauth-notebook"},
57+
{"name": "test-auth-notebook"},
5858
{
59-
"namespace": "test-oauth-notebook",
60-
"name": "test-oauth-notebook",
61-
"oauth_annotations": {
59+
"namespace": "test-auth-notebook",
60+
"name": "test-auth-notebook",
61+
"auth_annotations": {
6262
"notebooks.opendatahub.io/auth-sidecar-cpu-request": "200m",
6363
"notebooks.opendatahub.io/auth-sidecar-memory-request": "128Mi",
6464
"notebooks.opendatahub.io/auth-sidecar-cpu-limit": "500m",
@@ -69,18 +69,18 @@ def test_create_simple_notebook(
6969
],
7070
indirect=True,
7171
)
72-
def test_oauth_container_resource_customization(
72+
def test_auth_container_resource_customization(
7373
self,
7474
unprivileged_client: DynamicClient,
7575
unprivileged_model_namespace: Namespace,
7676
users_persistent_volume_claim: PersistentVolumeClaim,
7777
default_notebook: Notebook,
7878
):
7979
"""
80-
Test that OAuth container resource requests and limits can be customized using annotations.
80+
Test that Auth container resource requests and limits can be customized using annotations.
8181
82-
This test verifies that when a Notebook CR is created with custom OAuth container resource
83-
annotations, the spawned pod has the OAuth container with the specified resource values.
82+
This test verifies that when a Notebook CR is created with custom Auth container resource
83+
annotations, the spawned pod has the Auth container with the specified resource values.
8484
"""
8585
notebook_pod = Pod(
8686
client=unprivileged_client,
@@ -90,42 +90,42 @@ def test_oauth_container_resource_customization(
9090
notebook_pod.wait()
9191
notebook_pod.wait_for_condition(condition=Pod.Condition.READY, status=Pod.Condition.Status.TRUE)
9292

93-
# Verify OAuth container has the expected resource values
94-
oauth_container = self._get_oauth_container(pod=notebook_pod)
95-
assert oauth_container, "OAuth proxy container not found in the pod"
93+
# Verify Auth container has the expected resource values
94+
auth_container = self._get_auth_container(pod=notebook_pod)
95+
assert auth_container, "Auth proxy container not found in the pod"
9696

9797
# Check CPU request
98-
assert oauth_container.resources.requests["cpu"] == "200m", (
99-
f"Expected CPU request '200m', got '{oauth_container.resources.requests['cpu']}'"
98+
assert auth_container.resources.requests["cpu"] == "200m", (
99+
f"Expected CPU request '200m', got '{auth_container.resources.requests['cpu']}'"
100100
)
101101

102102
# Check memory request
103-
assert oauth_container.resources.requests["memory"] == "128Mi", (
104-
f"Expected memory request '128Mi', got '{oauth_container.resources.requests['memory']}'"
103+
assert auth_container.resources.requests["memory"] == "128Mi", (
104+
f"Expected memory request '128Mi', got '{auth_container.resources.requests['memory']}'"
105105
)
106106

107107
# Check CPU limit
108-
assert oauth_container.resources.limits["cpu"] == "500m", (
109-
f"Expected CPU limit '500m', got '{oauth_container.resources.limits['cpu']}'"
108+
assert auth_container.resources.limits["cpu"] == "500m", (
109+
f"Expected CPU limit '500m', got '{auth_container.resources.limits['cpu']}'"
110110
)
111111

112112
# Check memory limit
113-
assert oauth_container.resources.limits["memory"] == "256Mi", (
114-
f"Expected memory limit '256Mi', got '{oauth_container.resources.limits['memory']}'"
113+
assert auth_container.resources.limits["memory"] == "256Mi", (
114+
f"Expected memory limit '256Mi', got '{auth_container.resources.limits['memory']}'"
115115
)
116116

117-
def _get_oauth_container(self, pod: Pod):
117+
def _get_auth_container(self, pod: Pod):
118118
"""
119-
Find and return the OAuth proxy container from the pod spec.
119+
Find and return the Auth proxy container from the pod spec.
120120
121121
Args:
122122
pod: The pod instance to search
123123
124124
Returns:
125-
The OAuth container if found, None otherwise
125+
The Auth container if found, None otherwise
126126
"""
127127
containers = pod.instance.spec.containers
128128
for container in containers:
129-
if container.name == "oauth-proxy":
129+
if container.name == "kube-rbac-proxy":
130130
return container
131131
return None

utilities/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class KserveAuth:
190190
SECURITY: str = f"security.{ApiGroups.OPENDATAHUB_IO}/enable-auth"
191191

192192
class Notebook:
193-
INJECT_OAUTH: str = f"notebooks.{ApiGroups.OPENDATAHUB_IO}/inject-oauth"
193+
INJECT_AUTH: str = f"notebooks.{ApiGroups.OPENDATAHUB_IO}/inject-auth"
194194

195195
class OpenDataHubIo:
196196
MANAGED: str = Annotations.OpenDataHubIo.MANAGED

0 commit comments

Comments
 (0)