vantage6 5.0.0a35__py3-none-any.whl → 5.0.0a37__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vantage6 might be problematic. Click here for more details.

Files changed (84) hide show
  1. vantage6/cli/algorithm/generate_algorithm_json.py +9 -10
  2. vantage6/cli/algorithm/update.py +1 -1
  3. vantage6/cli/algostore/attach.py +1 -0
  4. vantage6/cli/algostore/files.py +3 -2
  5. vantage6/cli/algostore/list.py +0 -3
  6. vantage6/cli/algostore/new.py +3 -2
  7. vantage6/cli/algostore/start.py +14 -3
  8. vantage6/cli/algostore/stop.py +3 -0
  9. vantage6/cli/auth/attach.py +60 -0
  10. vantage6/cli/auth/files.py +16 -0
  11. vantage6/cli/auth/list.py +13 -0
  12. vantage6/cli/auth/new.py +81 -0
  13. vantage6/cli/auth/remove.py +31 -0
  14. vantage6/cli/auth/start.py +94 -0
  15. vantage6/cli/auth/stop.py +67 -0
  16. vantage6/cli/cli.py +56 -5
  17. vantage6/cli/common/decorator.py +24 -5
  18. vantage6/cli/common/new.py +27 -7
  19. vantage6/cli/common/start.py +49 -41
  20. vantage6/cli/common/stop.py +23 -5
  21. vantage6/cli/common/utils.py +25 -0
  22. vantage6/cli/config.py +10 -2
  23. vantage6/cli/{configuration_wizard.py → configuration_create.py} +28 -15
  24. vantage6/cli/configuration_manager.py +97 -17
  25. vantage6/cli/context/__init__.py +10 -5
  26. vantage6/cli/context/algorithm_store.py +11 -5
  27. vantage6/cli/context/auth.py +125 -0
  28. vantage6/cli/context/base_server.py +0 -4
  29. vantage6/cli/context/node.py +25 -8
  30. vantage6/cli/context/server.py +18 -6
  31. vantage6/cli/dev/clean.py +28 -0
  32. vantage6/cli/dev/common.py +34 -0
  33. vantage6/cli/dev/rebuild.py +39 -0
  34. vantage6/cli/dev/start.py +36 -0
  35. vantage6/cli/dev/stop.py +23 -0
  36. vantage6/cli/globals.py +5 -1
  37. vantage6/cli/node/common/__init__.py +26 -10
  38. vantage6/cli/node/list.py +5 -4
  39. vantage6/cli/node/new.py +13 -6
  40. vantage6/cli/node/set_api_key.py +1 -1
  41. vantage6/cli/node/start.py +19 -4
  42. vantage6/cli/node/stop.py +153 -7
  43. vantage6/cli/node/task_cleanup/__init__.py +153 -0
  44. vantage6/cli/node/version.py +5 -4
  45. vantage6/cli/prometheus/monitoring_manager.py +5 -3
  46. vantage6/cli/sandbox/config/base.py +101 -0
  47. vantage6/cli/sandbox/config/core.py +300 -0
  48. vantage6/cli/sandbox/config/node.py +314 -0
  49. vantage6/cli/sandbox/data/olympic_athletes_2016.csv +2425 -0
  50. vantage6/cli/sandbox/new.py +207 -0
  51. vantage6/cli/sandbox/populate/__init__.py +173 -0
  52. vantage6/cli/sandbox/populate/helpers/connect_store.py +203 -0
  53. vantage6/cli/sandbox/populate/helpers/delete_fixtures.py +67 -0
  54. vantage6/cli/sandbox/populate/helpers/load_fixtures.py +476 -0
  55. vantage6/cli/sandbox/populate/helpers/utils.py +35 -0
  56. vantage6/cli/sandbox/remove.py +173 -0
  57. vantage6/cli/sandbox/start.py +341 -0
  58. vantage6/cli/sandbox/stop.py +106 -0
  59. vantage6/cli/server/attach.py +1 -0
  60. vantage6/cli/server/common/__init__.py +6 -33
  61. vantage6/cli/server/import_.py +137 -119
  62. vantage6/cli/server/new.py +22 -7
  63. vantage6/cli/server/start.py +10 -1
  64. vantage6/cli/server/stop.py +2 -0
  65. vantage6/cli/template/auth_config.j2 +253 -0
  66. vantage6/cli/template/node_config.j2 +8 -8
  67. vantage6/cli/template/node_config_nonk8s.j2 +33 -0
  68. vantage6/cli/template/server_config.j2 +10 -7
  69. vantage6/cli/test/common/diagnostic_runner.py +5 -3
  70. vantage6/cli/use/namespace.py +2 -1
  71. vantage6/cli/utils.py +33 -1
  72. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/METADATA +4 -4
  73. vantage6-5.0.0a37.dist-info/RECORD +97 -0
  74. vantage6/cli/dev/create.py +0 -693
  75. vantage6/cli/dev/remove.py +0 -112
  76. vantage6/cli/rabbitmq/__init__.py +0 -0
  77. vantage6/cli/rabbitmq/definitions.py +0 -26
  78. vantage6/cli/rabbitmq/queue_manager.py +0 -218
  79. vantage6/cli/rabbitmq/rabbitmq.config +0 -8
  80. vantage6/cli/server/shell.py +0 -54
  81. vantage6-5.0.0a35.dist-info/RECORD +0 -75
  82. /vantage6/cli/{dev → sandbox}/data/km_dataset.csv +0 -0
  83. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/WHEEL +0 -0
  84. {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,153 @@
1
+ import logging
2
+
3
+ from kubernetes import client as k8s_client
4
+ from kubernetes.client.rest import ApiException
5
+
6
+ from vantage6.common import logger_name
7
+
8
+ log = logging.getLogger(logger_name(__name__))
9
+
10
+
11
+ def delete_job_related_pods(
12
+ run_id: int,
13
+ container_name: str,
14
+ namespace: str,
15
+ core_api: k8s_client.CoreV1Api,
16
+ batch_api: k8s_client.BatchV1Api,
17
+ ) -> None:
18
+ """
19
+ Deletes all the PODs created by a Kubernetes job in a given namespace
20
+
21
+ Parameters
22
+ ----------
23
+ run_id: int
24
+ Server run identifier
25
+ container_name: str
26
+ Name of the container
27
+ namespace: str
28
+ Namespace where the container is located
29
+ core_api: k8s_client.CoreV1Api
30
+ Kubernetes Core API instance
31
+ batch_api: k8s_client.BatchV1Api
32
+ Kubernetes Batch API instance
33
+ """
34
+ log.info(
35
+ "Cleaning up kubernetes Job %s (run_id = %s) and related PODs",
36
+ container_name,
37
+ run_id,
38
+ )
39
+
40
+ __delete_job(container_name, namespace, batch_api)
41
+
42
+ job_selector = f"job-name={container_name}"
43
+ job_pods_list = core_api.list_namespaced_pod(namespace, label_selector=job_selector)
44
+ for job_pod in job_pods_list.items:
45
+ __delete_pod(job_pod.metadata.name, namespace, core_api)
46
+
47
+ __delete_secret(container_name, namespace, core_api)
48
+
49
+
50
+ def __delete_secret(
51
+ secret_name: str, namespace: str, core_api: k8s_client.CoreV1Api
52
+ ) -> None:
53
+ """
54
+ Deletes a secret in a given namespace
55
+
56
+ Parameters
57
+ ----------
58
+ secret_name: str
59
+ Name of the secret
60
+ namespace: str
61
+ Namespace where the secret is located
62
+ core_api: k8s_client.CoreV1Api
63
+ Kubernetes Core API instance
64
+ """
65
+ try:
66
+ core_api.delete_namespaced_secret(name=secret_name, namespace=namespace)
67
+ log.info(
68
+ "Removed kubernetes Secret %s in namespace %s",
69
+ secret_name,
70
+ namespace,
71
+ )
72
+ except ApiException as exc:
73
+ if exc.status == 404:
74
+ log.debug("No secret %s to remove in namespace %s", secret_name, namespace)
75
+ else:
76
+ log.error("Exception when deleting namespaced secret: %s", exc)
77
+
78
+
79
+ def __delete_job(
80
+ job_name: str, namespace: str, batch_api: k8s_client.BatchV1Api
81
+ ) -> None:
82
+ """
83
+ Deletes a job in a given namespace
84
+
85
+ Parameters
86
+ ----------
87
+ job_name: str
88
+ Name of the job
89
+ namespace: str
90
+ Namespace where the job is located
91
+ batch_api: k8s_client.BatchV1Api
92
+ Kubernetes Batch API instance
93
+ """
94
+ log.info(
95
+ "Cleaning up kubernetes Job %s and related PODs",
96
+ job_name,
97
+ )
98
+ try:
99
+ # Check if the job exists before attempting to delete it
100
+ job = batch_api.read_namespaced_job(name=job_name, namespace=namespace)
101
+ if job:
102
+ batch_api.delete_namespaced_job(name=job_name, namespace=namespace)
103
+ else:
104
+ log.warning(
105
+ "Job %s not found in namespace %s, skipping deletion",
106
+ job_name,
107
+ namespace,
108
+ )
109
+ except ApiException as exc:
110
+ if exc.status == 404:
111
+ log.warning(
112
+ "Job %s not found in namespace %s, skipping deletion",
113
+ job_name,
114
+ namespace,
115
+ )
116
+ else:
117
+ log.error("Exception when deleting namespaced job: %s", exc)
118
+
119
+
120
+ def __delete_pod(pod_name: str, namespace: str, core_api: k8s_client.CoreV1Api) -> None:
121
+ """
122
+ Deletes a job in a given namespace
123
+
124
+ Parameters
125
+ ----------
126
+ pod_name: str
127
+ Name of the job
128
+ namespace: str
129
+ Namespace where the job is located
130
+ core_api: k8s_client.CoreV1Api
131
+ Kubernetes Core API instance
132
+ """
133
+ log.info("Cleaning up kubernetes pod %s in namespace %s", pod_name, namespace)
134
+ try:
135
+ # Check if the job exists before attempting to delete it
136
+ job = core_api.read_namespaced_pod(name=pod_name, namespace=namespace)
137
+ if job:
138
+ core_api.delete_namespaced_pod(name=pod_name, namespace=namespace)
139
+ else:
140
+ log.warning(
141
+ "Pod %s not found in namespace %s, skipping deletion",
142
+ pod_name,
143
+ namespace,
144
+ )
145
+ except ApiException as exc:
146
+ if exc.status == 404:
147
+ log.warning(
148
+ "Pod %s not found in namespace %s, skipping deletion",
149
+ pod_name,
150
+ namespace,
151
+ )
152
+ else:
153
+ log.error("Exception when deleting namespaced job: %s", exc)
@@ -1,12 +1,13 @@
1
1
  import click
2
- import questionary as q
3
2
  import docker
3
+ import questionary as q
4
4
 
5
5
  from vantage6.common import error
6
- from vantage6.common.globals import APPNAME
7
6
  from vantage6.common.docker.addons import check_docker_running
8
- from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
7
+ from vantage6.common.globals import APPNAME
8
+
9
9
  from vantage6.cli import __version__
10
+ from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
10
11
  from vantage6.cli.node.common import find_running_node_names
11
12
 
12
13
 
@@ -16,7 +17,7 @@ from vantage6.cli.node.common import find_running_node_names
16
17
  "--system",
17
18
  "system_folders",
18
19
  flag_value=True,
19
- help="Search for configuration in system folders rather than " "user folders",
20
+ help="Search for configuration in system folders rather than user folders",
20
21
  )
21
22
  @click.option(
22
23
  "--user",
@@ -1,10 +1,12 @@
1
- import yaml
2
- import docker
3
1
  from pathlib import Path
4
2
 
5
- from vantage6.common import info, error
3
+ import docker
4
+ import yaml
5
+
6
+ from vantage6.common import error, info
6
7
  from vantage6.common.docker.network_manager import NetworkManager
7
8
  from vantage6.common.globals import DEFAULT_PROMETHEUS_EXPORTER_PORT
9
+
8
10
  from vantage6.cli.context.server import ServerContext
9
11
  from vantage6.cli.globals import (
10
12
  DEFAULT_PROMETHEUS_IMAGE,
@@ -0,0 +1,101 @@
1
+ from pathlib import Path
2
+
3
+ import yaml
4
+
5
+ from vantage6.common.globals import InstanceType
6
+
7
+ from vantage6.cli.context import select_context_class
8
+ from vantage6.cli.sandbox.populate.helpers.utils import replace_wsl_path
9
+
10
+
11
+ class BaseSandboxConfigManager:
12
+ """
13
+ Base class for sandbox configuration managers.
14
+
15
+ Parameters
16
+ ----------
17
+ server_name : str
18
+ Name of the server.
19
+ custom_data_dir : Path | None
20
+ Path to the custom data directory. Useful on WSL because of mount issues for
21
+ default directories.
22
+ """
23
+
24
+ def __init__(self, server_name: str, custom_data_dir: Path | None) -> None:
25
+ self.server_name = server_name
26
+ self.custom_data_dir = Path(custom_data_dir) if custom_data_dir else None
27
+
28
+ @staticmethod
29
+ def _read_extra_config_file(extra_config_file: Path | None) -> dict:
30
+ """Reads extra configuration file.
31
+
32
+ Parameters
33
+ ----------
34
+ extra_config_file : Path | None
35
+ Path to file with additional configuration.
36
+
37
+ Returns
38
+ -------
39
+ dict
40
+ Extra configuration parsed from YAML. Empty dict if none provided.
41
+ """
42
+ if extra_config_file:
43
+ with open(extra_config_file, "r", encoding="utf-8") as f:
44
+ loaded = yaml.safe_load(f) or {}
45
+ if not isinstance(loaded, dict):
46
+ # Ensure we always return a dictionary
47
+ return {"value": loaded}
48
+ return loaded
49
+ return {}
50
+
51
+ def _create_and_get_data_dir(
52
+ self, instance_type: InstanceType, is_data_folder: bool = False
53
+ ) -> Path:
54
+ """
55
+ Create and get the data directory.
56
+
57
+ Parameters
58
+ ----------
59
+ instance_type: InstanceType
60
+ Type of vantage6 component
61
+ is_data_folder: bool
62
+ Whether or not to create the data folder or a config folder. This is only
63
+ used for node databases. Default is False.
64
+
65
+ Returns
66
+ -------
67
+ Path
68
+ Path to the data directory
69
+ """
70
+ ctx_class = select_context_class(instance_type)
71
+ folders = ctx_class.instance_folders(
72
+ instance_type=InstanceType.SERVER,
73
+ instance_name=self.server_name,
74
+ system_folders=False,
75
+ )
76
+ main_data_dir = (
77
+ Path(folders["dev"]) if not self.custom_data_dir else self.custom_data_dir
78
+ )
79
+
80
+ if instance_type == InstanceType.SERVER:
81
+ data_dir = main_data_dir / self.server_name / "server"
82
+ elif instance_type == InstanceType.ALGORITHM_STORE:
83
+ data_dir = main_data_dir / self.server_name / "store"
84
+ elif instance_type == InstanceType.NODE:
85
+ if is_data_folder:
86
+ last_subfolder = "data"
87
+ else:
88
+ last_subfolder = "node"
89
+ data_dir = main_data_dir / self.server_name / last_subfolder
90
+ else:
91
+ raise ValueError(f"Invalid instance type to get data dir: {instance_type}")
92
+
93
+ # For the directory to be created, ensure that if a WSL path is used, the path
94
+ # is converted to /mnt/wsl to create the directory on the host (not
95
+ # /run/desktop/mnt/host/wsl as will raise non-existent directory errors)
96
+ data_dir = replace_wsl_path(data_dir, to_mnt_wsl=True)
97
+ data_dir.mkdir(parents=True, exist_ok=True)
98
+ # now ensure that the wsl path is properly replaced to /run/desktop/mnt/host/wsl
99
+ # if it is a WSL path, because that path will be used in the node configuration
100
+ # files and is required to successfully mount the volumes.
101
+ return replace_wsl_path(data_dir, to_mnt_wsl=False)
@@ -0,0 +1,300 @@
1
+ from pathlib import Path
2
+
3
+ from vantage6.common.globals import HTTP_LOCALHOST, InstanceType, Ports
4
+
5
+ from vantage6.cli.common.new import new
6
+ from vantage6.cli.sandbox.config.base import BaseSandboxConfigManager
7
+
8
+
9
+ class CoreSandboxConfigManager(BaseSandboxConfigManager):
10
+ """
11
+ Class to store the sandbox configurations.
12
+
13
+ Parameters
14
+ ----------
15
+ server_name : str
16
+ Name of the server.
17
+ server_port : int
18
+ Port of the server.
19
+ ui_port : int
20
+ Port of the UI.
21
+ algorithm_store_port : int
22
+ Port of the algorithm store.
23
+ server_image : str | None
24
+ Image of the server.
25
+ store_image : str | None
26
+ Image of the algorithm store.
27
+ ui_image : str | None
28
+ Image of the UI.
29
+ extra_server_config : Path | None
30
+ Path to the extra server configuration file.
31
+ extra_store_config : Path | None
32
+ Path to the extra algorithm store configuration file.
33
+ context : str | None
34
+ Kubernetes context.
35
+ namespace : str | None
36
+ Kubernetes namespace.
37
+ k8s_node_name : str
38
+ Kubernetes node name.
39
+ custom_data_dir : Path | None
40
+ Path to the custom data directory. Useful on WSL because of mount issues for
41
+ default directories.
42
+ """
43
+
44
+ def __init__(
45
+ self,
46
+ server_name: str,
47
+ server_port: int,
48
+ ui_port: int,
49
+ algorithm_store_port: int,
50
+ server_image: str | None,
51
+ store_image: str | None,
52
+ ui_image: str | None,
53
+ extra_server_config: Path | None,
54
+ extra_store_config: Path | None,
55
+ extra_auth_config: Path | None,
56
+ context: str,
57
+ namespace: str,
58
+ k8s_node_name: str,
59
+ custom_data_dir: Path | None = None,
60
+ ) -> None:
61
+ super().__init__(server_name, custom_data_dir)
62
+
63
+ self.server_port = server_port
64
+ self.ui_port = ui_port
65
+ self.algorithm_store_port = algorithm_store_port
66
+ self.server_image = server_image
67
+ self.store_image = store_image
68
+ self.ui_image = ui_image
69
+ self.extra_server_config = extra_server_config
70
+ self.extra_store_config = extra_store_config
71
+ self.extra_auth_config = extra_auth_config
72
+ self.context = context
73
+ self.namespace = namespace
74
+
75
+ self.server_config_file = None
76
+ self.store_config_file = None
77
+ self.auth_config_file = None
78
+ self.k8s_node_name = k8s_node_name
79
+
80
+ def generate_server_configs(self) -> None:
81
+ """Generates the demo network."""
82
+
83
+ self._create_auth_config()
84
+
85
+ self._create_vserver_config()
86
+
87
+ self._create_algo_store_config()
88
+
89
+ def __server_config_return_func(self, extra_config: dict, data_dir: Path) -> dict:
90
+ """
91
+ Return a dict with server configuration values to be used in creating the
92
+ config file.
93
+
94
+ Parameters
95
+ ----------
96
+ extra_config : dict
97
+ Extra configuration (parsed from YAML) to be added to the server
98
+ configuration.
99
+ data_dir : Path
100
+ Path to the data directory.
101
+
102
+ Returns
103
+ -------
104
+ dict
105
+ Dictionary with server configuration values.
106
+ """
107
+ store_service = (
108
+ f"vantage6-{self.server_name}-store-user-algorithm-store-store-service"
109
+ )
110
+ store_address = (
111
+ f"http://{store_service}.{self.namespace}.svc.cluster.local:"
112
+ f"{Ports.DEV_ALGO_STORE}"
113
+ )
114
+ config = {
115
+ "server": {
116
+ "baseUrl": f"{HTTP_LOCALHOST}:{self.server_port}",
117
+ # TODO: v5+ set to latest v5 image
118
+ # TODO make this configurable
119
+ "image": (
120
+ self.server_image
121
+ or "harbor2.vantage6.ai/infrastructure/server:5.0.0a36"
122
+ ),
123
+ "algorithm_stores": [
124
+ {
125
+ "name": "Local store",
126
+ "url": store_address,
127
+ "api_path": "/store",
128
+ }
129
+ ],
130
+ "logging": {
131
+ "level": "DEBUG",
132
+ },
133
+ "jwt": {
134
+ "secret": "development-constant-secret!",
135
+ },
136
+ "dev": {
137
+ "host_uri": (
138
+ "host.docker.internal"
139
+ if self.k8s_node_name == "docker-desktop"
140
+ else "172.17.0.1"
141
+ ),
142
+ "store_address": store_address,
143
+ },
144
+ "keycloakUrl": (
145
+ f"http://vantage6-{self.server_name}-auth-user-auth-keycloak."
146
+ f"{self.namespace}.svc.cluster.local"
147
+ ),
148
+ },
149
+ "rabbitmq": {},
150
+ "database": {
151
+ "volumePath": str(data_dir),
152
+ "k8sNodeName": self.k8s_node_name,
153
+ },
154
+ "ui": {
155
+ "port": self.ui_port,
156
+ # TODO: v5+ set to latest v5 image
157
+ # TODO: make this configurable
158
+ "image": (
159
+ self.ui_image or "harbor2.vantage6.ai/infrastructure/ui:5.0.0a36"
160
+ ),
161
+ },
162
+ }
163
+
164
+ # merge the extra config with the server config
165
+ if extra_config is not None:
166
+ config.update(extra_config)
167
+
168
+ return config
169
+
170
+ def _create_vserver_config(self) -> None:
171
+ """Creates server configuration file (YAML)."""
172
+
173
+ data_dir = self._create_and_get_data_dir(instance_type=InstanceType.SERVER)
174
+
175
+ extra_config = self._read_extra_config_file(self.extra_server_config)
176
+ if self.ui_image is not None:
177
+ ui_config = extra_config.get("ui", {}) if extra_config is not None else {}
178
+ ui_config["image"] = self.ui_image
179
+ extra_config["ui"] = ui_config
180
+
181
+ # Create the server config file
182
+ self.server_config_file = new(
183
+ config_producing_func=self.__server_config_return_func,
184
+ config_producing_func_args=(extra_config, data_dir),
185
+ name=self.server_name,
186
+ system_folders=False,
187
+ namespace=self.namespace,
188
+ context=self.context,
189
+ type_=InstanceType.SERVER,
190
+ is_sandbox=True,
191
+ )
192
+
193
+ def _create_algo_store_config(self) -> None:
194
+ """Create algorithm store configuration file (YAML)."""
195
+
196
+ extra_config = self._read_extra_config_file(self.extra_store_config)
197
+
198
+ data_dir = self._create_and_get_data_dir(InstanceType.ALGORITHM_STORE)
199
+
200
+ self.store_config_file = new(
201
+ config_producing_func=self.__algo_store_config_return_func,
202
+ config_producing_func_args=(extra_config, data_dir),
203
+ name=f"{self.server_name}-store",
204
+ system_folders=False,
205
+ namespace=self.namespace,
206
+ context=self.context,
207
+ type_=InstanceType.ALGORITHM_STORE,
208
+ is_sandbox=True,
209
+ )
210
+
211
+ def __algo_store_config_return_func(
212
+ self, extra_config: dict, data_dir: Path
213
+ ) -> dict:
214
+ """
215
+ Return a dict with algorithm store configuration values to be used in creating
216
+ the config file.
217
+
218
+ Returns
219
+ -------
220
+ dict
221
+ Dictionary with algorithm store configuration values.
222
+ """
223
+ config = {
224
+ "store": {
225
+ "internal": {
226
+ "port": self.algorithm_store_port,
227
+ },
228
+ "logging": {
229
+ "level": "DEBUG",
230
+ },
231
+ "vantage6ServerUri": f"{HTTP_LOCALHOST}:{self.server_port}",
232
+ "image": (
233
+ self.store_image
234
+ or "harbor2.vantage6.ai/infrastructure/algorithm-store:5.0.0a36"
235
+ ),
236
+ "keycloakUrl": (
237
+ f"http://vantage6-{self.server_name}-auth-user-auth-keycloak."
238
+ f"{self.namespace}.svc.cluster.local"
239
+ ),
240
+ "policies": {
241
+ "allowLocalhost": True,
242
+ "assignReviewOwnAlgorithm": True,
243
+ },
244
+ "dev": {
245
+ "host_uri": (
246
+ "host.docker.internal"
247
+ if self.k8s_node_name == "docker-desktop"
248
+ else "172.17.0.1"
249
+ ),
250
+ "disable_review": True,
251
+ "review_own_algorithm": True,
252
+ },
253
+ },
254
+ "database": {
255
+ "volumePath": str(data_dir),
256
+ "k8sNodeName": self.k8s_node_name,
257
+ },
258
+ }
259
+
260
+ # merge the extra config with the algorithm store config
261
+ if extra_config is not None:
262
+ config.update(extra_config)
263
+
264
+ return config
265
+
266
+ def _create_auth_config(self) -> None:
267
+ """Create auth configuration file (YAML)."""
268
+ self.auth_config_file = new(
269
+ config_producing_func=self.__auth_config_return_func,
270
+ config_producing_func_args=(self.extra_auth_config,),
271
+ name=f"{self.server_name}-auth",
272
+ system_folders=False,
273
+ namespace=self.namespace,
274
+ context=self.context,
275
+ type_=InstanceType.AUTH,
276
+ is_sandbox=True,
277
+ )
278
+
279
+ def __auth_config_return_func(self, extra_config: dict) -> dict:
280
+ """
281
+ Return a dict with auth configuration values to be used in creating the
282
+ config file.
283
+ """
284
+
285
+ config = {
286
+ "keycloak": {
287
+ "production": False,
288
+ "no_password_update_required": True,
289
+ "redirectUris": [
290
+ f"{HTTP_LOCALHOST}:7600",
291
+ f"{HTTP_LOCALHOST}:7681",
292
+ ],
293
+ },
294
+ }
295
+
296
+ # merge the extra config with the auth config
297
+ if extra_config is not None:
298
+ config.update(extra_config)
299
+
300
+ return config