Skip to content

Commit cfb4e64

Browse files
Merge pull request #3641 from GeorgianaElena/configurator-schema
Make sure the configurator is disabled when appropriate
2 parents e04c26c + 897839a commit cfb4e64

File tree

1 file changed

+80
-14
lines changed

1 file changed

+80
-14
lines changed

deployer/commands/validate/config.py

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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()
7384
def 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()
240306
def all(
241307
cluster_name: str = typer.Argument(..., help="Name of cluster to operate on"),

0 commit comments

Comments
 (0)