@@ -69,6 +69,17 @@ def _prepare_helm_charts_dependencies_and_schemas():
6969 subprocess .check_call (["helm" , "dep" , "up" , support_dir ])
7070
7171
72+ def get_list_of_hubs_to_operate_on (cluster_name , hub_name ):
73+ config_file_path = find_absolute_path_to_cluster_file (cluster_name )
74+ with open (config_file_path ) as f :
75+ cluster = Cluster (yaml .load (f ), config_file_path .parent )
76+
77+ if hub_name :
78+ return [h for h in cluster .hubs if h .spec ["name" ] == hub_name ]
79+
80+ return cluster .hubs
81+
82+
7283@validate_app .command ()
7384def cluster_config (
7485 cluster_name : str = typer .Argument (..., help = "Name of cluster to operate on" ),
@@ -99,14 +110,8 @@ def hub_config(
99110 _prepare_helm_charts_dependencies_and_schemas ()
100111
101112 config_file_path = find_absolute_path_to_cluster_file (cluster_name )
102- with open (config_file_path ) as f :
103- cluster = Cluster (yaml .load (f ), config_file_path .parent )
104113
105- hubs = []
106- if hub_name :
107- hubs = [h for h in cluster .hubs if h .spec ["name" ] == hub_name ]
108- else :
109- hubs = cluster .hubs
114+ hubs = get_list_of_hubs_to_operate_on (cluster_name , hub_name )
110115
111116 for i , hub in enumerate (hubs ):
112117 print_colour (
@@ -185,14 +190,8 @@ def authenticator_config(
185190 _prepare_helm_charts_dependencies_and_schemas ()
186191
187192 config_file_path = find_absolute_path_to_cluster_file (cluster_name )
188- with open (config_file_path ) as f :
189- cluster = Cluster (yaml .load (f ), config_file_path .parent )
190193
191- hubs = []
192- if hub_name :
193- hubs = [h for h in cluster .hubs if h .spec ["name" ] == hub_name ]
194- else :
195- hubs = cluster .hubs
194+ hubs = get_list_of_hubs_to_operate_on (cluster_name , hub_name )
196195
197196 for i , hub in enumerate (hubs ):
198197 print_colour (
@@ -236,6 +235,73 @@ def authenticator_config(
236235 )
237236
238237
238+ @validate_app .command ()
239+ def configurator_config (
240+ cluster_name : str = typer .Argument (..., help = "Name of cluster to operate on" ),
241+ hub_name : str = typer .Argument (None , help = "Name of hub to operate on" ),
242+ ):
243+ """
244+ For each hub of a specific cluster:
245+ - It asserts that when the singleuser configuration overrides the same fields like the configurator, specifically kubespawner_override and profile_options,
246+ the latter must be disabled.
247+ An error is raised otherwise.
248+ """
249+ _prepare_helm_charts_dependencies_and_schemas ()
250+
251+ config_file_path = find_absolute_path_to_cluster_file (cluster_name )
252+
253+ hubs = get_list_of_hubs_to_operate_on (cluster_name , hub_name )
254+
255+ for i , hub in enumerate (hubs ):
256+ print_colour (
257+ f"{ i + 1 } / { len (hubs )} : Validating configurator and profile lists config for { hub .spec ['name' ]} ..."
258+ )
259+
260+ configurator_enabled = False
261+ singleuser_overrides = False
262+ for values_file_name in hub .spec ["helm_chart_values_files" ]:
263+ if "secret" not in os .path .basename (values_file_name ):
264+ values_file = config_file_path .parent .joinpath (values_file_name )
265+ # Load the hub extra config from its specific values files
266+ config = yaml .load (values_file )
267+ try :
268+ if hub .spec ["helm_chart" ] != "basehub" :
269+ singleuser_config = config ["basehub" ]["jupyterhub" ][
270+ "singleuser"
271+ ]
272+ custom_config = config ["basehub" ]["jupyterhub" ]["custom" ]
273+ else :
274+ singleuser_config = config ["jupyterhub" ]["singleuser" ]
275+ custom_config = config ["jupyterhub" ]["custom" ]
276+
277+ configurator_enabled = custom_config .get (
278+ "jupyterhubConfigurator" , {}
279+ ).get ("enabled" )
280+ # If it's already disabled we don't have what to check
281+ if configurator_enabled :
282+ profiles = singleuser_config .get ("profileList" , None )
283+ if profiles :
284+ for p in profiles :
285+ overrides = p .get ("kubespawner_override" , None )
286+ if overrides and overrides .get ("image" , None ):
287+ singleuser_overrides = True
288+ break
289+ options = p .get ("profile_options" , None )
290+ if options and "image" in options :
291+ singleuser_overrides = True
292+ break
293+ except KeyError :
294+ pass
295+
296+ if configurator_enabled == True and singleuser_overrides == True :
297+ raise ValueError (
298+ f"""
299+ When the singleuser configuration overrides the same fields like the configurator,
300+ the later must be disabled. Please disable the configurator for { hub .spec ['name' ]} .
301+ """
302+ )
303+
304+
239305@validate_app .command ()
240306def all (
241307 cluster_name : str = typer .Argument (..., help = "Name of cluster to operate on" ),
0 commit comments