11import pytest
2-
2+ from kubernetes .client import (
3+ V1Container ,
4+ V1EnvVar ,
5+ V1EnvVarSource ,
6+ V1LabelSelector ,
7+ V1PodSpec ,
8+ V1PodTemplateSpec ,
9+ V1StatefulSet ,
10+ V1StatefulSetSpec ,
11+ )
12+
13+ from renku_notebooks .api .classes .auth import RenkuTokens
314from renku_notebooks .api .classes .k8s_client import JsServerCache , K8sClient , NamespacedK8sClient
415from renku_notebooks .errors .intermittent import JSCacheError
516from renku_notebooks .errors .programming import ProgrammingError
17+ from renku_notebooks .util .kubernetes_ import find_env_var
618
719
820@pytest .fixture
@@ -37,9 +49,7 @@ def test_list_cache_preference(mock_server_cache, mock_namespaced_client):
3749 renku_ns_client = mock_namespaced_client ("renku" )
3850 sessions_ns_client = mock_namespaced_client ("renku-sessions" )
3951 sample_server_manifest = {"metadata" : {"labels" : {"username" : "username" }, "name" : "server1" }}
40- sample_server_manifest_preferred = {
41- "metadata" : {"labels" : {"username" : "username" }, "name" : "preferred" }
42- }
52+ sample_server_manifest_preferred = {"metadata" : {"labels" : {"username" : "username" }, "name" : "preferred" }}
4353 mock_server_cache .list_servers .return_value = [sample_server_manifest_preferred ]
4454 renku_ns_client .list_servers .return_value = []
4555 sessions_ns_client .list_servers .return_value = [sample_server_manifest ]
@@ -86,9 +96,7 @@ def test_get_two_results_raises_error(mock_server_cache, mock_namespaced_client)
8696def test_get_cache_is_preferred (mock_server_cache , mock_namespaced_client ):
8797 renku_ns_client = mock_namespaced_client ("renku" )
8898 sessions_ns_client = mock_namespaced_client ("renku-sessions" )
89- sample_server_manifest_cache = {
90- "metadata" : {"labels" : {"username" : "username" }, "name" : "server" }
91- }
99+ sample_server_manifest_cache = {"metadata" : {"labels" : {"username" : "username" }, "name" : "server" }}
92100 sample_server_manifest_non_cache = {
93101 "metadata" : {
94102 "labels" : {"username" : "username" , "not_preferred" : True },
@@ -112,3 +120,82 @@ def test_get_server_no_match(mock_server_cache, mock_namespaced_client):
112120 client = K8sClient (mock_server_cache , renku_ns_client , "username" , sessions_ns_client )
113121 server = client .get_server ("server" , "username" )
114122 assert server is None
123+
124+
125+ def test_find_env_var ():
126+ container = V1Container (
127+ name = "test" , env = [V1EnvVar (name = "key1" , value = "val1" ), V1EnvVar (name = "key2" , value_from = V1EnvVarSource ())]
128+ )
129+ assert find_env_var (container , "key1" ) == (0 , "val1" )
130+ assert find_env_var (container , "key2" ) == (1 , V1EnvVarSource ())
131+ assert find_env_var (container , "missing" ) is None
132+
133+
134+ def test_patch_statefulset_tokens ():
135+ git_clone_access_env = "GIT_CLONE_USER__RENKU_TOKEN"
136+ git_proxy_access_env = "GIT_PROXY_RENKU_ACCESS_TOKEN"
137+ git_proxy_refresh_env = "GIT_PROXY_RENKU_REFRESH_TOKEN"
138+ secrets_access_env = "RENKU_ACCESS_TOKEN"
139+ git_clone = V1Container (
140+ name = "git-clone" ,
141+ env = [
142+ V1EnvVar (name = "test" , value = "value" ),
143+ V1EnvVar (git_clone_access_env , "old_value" ),
144+ V1EnvVar (name = "test-from-source" , value_from = V1EnvVarSource ()),
145+ ],
146+ )
147+ git_proxy = V1Container (
148+ name = "git-proxy" ,
149+ env = [
150+ V1EnvVar (name = "test" , value = "value" ),
151+ V1EnvVar (name = "test-from-source" , value_from = V1EnvVarSource ()),
152+ V1EnvVar (git_proxy_refresh_env , "old_value" ),
153+ V1EnvVar (git_proxy_access_env , "old_value" ),
154+ ],
155+ )
156+ secrets = V1Container (
157+ name = "init-user-secrets" ,
158+ env = [
159+ V1EnvVar (secrets_access_env , "old_value" ),
160+ V1EnvVar (name = "test" , value = "value" ),
161+ V1EnvVar (name = "test-from-source" , value_from = V1EnvVarSource ()),
162+ ],
163+ )
164+ random1 = V1Container (name = "random1" )
165+ random2 = V1Container (
166+ name = "random2" ,
167+ env = [
168+ V1EnvVar (name = "test" , value = "value" ),
169+ V1EnvVar (name = "test-from-source" , value_from = V1EnvVarSource ()),
170+ ],
171+ )
172+
173+ new_renku_tokens = RenkuTokens (access_token = "new_renku_access_token" , refresh_token = "new_renku_refresh_token" )
174+
175+ sts = V1StatefulSet (
176+ spec = V1StatefulSetSpec (
177+ service_name = "test" ,
178+ selector = V1LabelSelector (),
179+ template = V1PodTemplateSpec (
180+ spec = V1PodSpec (
181+ containers = [git_proxy , random1 , random2 ], init_containers = [git_clone , random1 , secrets , random2 ]
182+ )
183+ ),
184+ )
185+ )
186+ patches = NamespacedK8sClient ._get_statefulset_token_patches (sts , new_renku_tokens )
187+
188+ # Order of patches should be git proxy access, git proxy refresh, git clone, secrets
189+ assert len (patches ) == 4
190+ # Git proxy access token
191+ assert patches [0 ]["path" ] == "/spec/template/spec/containers/0/env/3/value"
192+ assert patches [0 ]["value" ] == new_renku_tokens .access_token
193+ # Git proxy refresh token
194+ assert patches [1 ]["path" ] == "/spec/template/spec/containers/0/env/2/value"
195+ assert patches [1 ]["value" ] == new_renku_tokens .refresh_token
196+ # Git clone
197+ assert patches [2 ]["path" ] == "/spec/template/spec/initContainers/0/env/1/value"
198+ assert patches [2 ]["value" ] == new_renku_tokens .access_token
199+ # Secrets init
200+ assert patches [3 ]["path" ] == "/spec/template/spec/initContainers/2/env/0/value"
201+ assert patches [3 ]["value" ] == new_renku_tokens .access_token
0 commit comments