vantage6 5.0.0a37__py3-none-any.whl → 5.0.0a40__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 (50) hide show
  1. vantage6/cli/algorithm/generate_algorithm_json.py +2 -1
  2. vantage6/cli/algostore/attach.py +28 -3
  3. vantage6/cli/algostore/list.py +2 -2
  4. vantage6/cli/algostore/start.py +11 -3
  5. vantage6/cli/algostore/version.py +62 -0
  6. vantage6/cli/auth/attach.py +1 -1
  7. vantage6/cli/auth/list.py +2 -2
  8. vantage6/cli/auth/remove.py +58 -0
  9. vantage6/cli/auth/start.py +12 -8
  10. vantage6/cli/cli.py +2 -0
  11. vantage6/cli/common/attach.py +114 -0
  12. vantage6/cli/common/decorator.py +9 -6
  13. vantage6/cli/common/list.py +68 -0
  14. vantage6/cli/common/new.py +3 -2
  15. vantage6/cli/common/remove.py +18 -0
  16. vantage6/cli/common/stop.py +6 -11
  17. vantage6/cli/common/utils.py +44 -76
  18. vantage6/cli/common/version.py +82 -0
  19. vantage6/cli/configuration_create.py +3 -2
  20. vantage6/cli/context/__init__.py +3 -0
  21. vantage6/cli/context/algorithm_store.py +2 -2
  22. vantage6/cli/node/attach.py +27 -3
  23. vantage6/cli/node/common/__init__.py +31 -6
  24. vantage6/cli/node/create_private_key.py +11 -10
  25. vantage6/cli/node/list.py +3 -44
  26. vantage6/cli/node/set_api_key.py +12 -6
  27. vantage6/cli/node/start.py +11 -3
  28. vantage6/cli/node/stop.py +13 -15
  29. vantage6/cli/node/version.py +96 -33
  30. vantage6/cli/sandbox/config/base.py +10 -2
  31. vantage6/cli/sandbox/config/core.py +3 -3
  32. vantage6/cli/sandbox/config/node.py +2 -5
  33. vantage6/cli/sandbox/remove.py +17 -35
  34. vantage6/cli/sandbox/start.py +8 -0
  35. vantage6/cli/sandbox/stop.py +1 -1
  36. vantage6/cli/server/attach.py +28 -3
  37. vantage6/cli/server/import_.py +85 -17
  38. vantage6/cli/server/list.py +2 -2
  39. vantage6/cli/server/start.py +11 -3
  40. vantage6/cli/server/version.py +31 -18
  41. vantage6/cli/template/algo_store_config.j2 +3 -0
  42. vantage6/cli/template/node_config.j2 +3 -1
  43. vantage6/cli/use/context.py +8 -1
  44. vantage6/cli/use/namespace.py +10 -7
  45. vantage6/cli/utils_kubernetes.py +270 -0
  46. {vantage6-5.0.0a37.dist-info → vantage6-5.0.0a40.dist-info}/METADATA +3 -3
  47. {vantage6-5.0.0a37.dist-info → vantage6-5.0.0a40.dist-info}/RECORD +50 -45
  48. /vantage6/cli/node/{task_cleanup/__init__.py → common/task_cleanup.py} +0 -0
  49. {vantage6-5.0.0a37.dist-info → vantage6-5.0.0a40.dist-info}/WHEEL +0 -0
  50. {vantage6-5.0.0a37.dist-info → vantage6-5.0.0a40.dist-info}/entry_points.txt +0 -0
@@ -1,19 +1,20 @@
1
1
  import json
2
2
  import subprocess
3
3
  from pathlib import Path
4
- from subprocess import Popen
5
4
  from typing import Iterable
6
5
 
7
- import click
8
6
  import docker
9
7
  import questionary as q
10
- from colorama import Fore, Style
11
8
 
12
- from vantage6.common import error, warning
13
- from vantage6.common.globals import APPNAME, STRING_ENCODING, InstanceType
9
+ from vantage6.common import error
10
+ from vantage6.common.globals import (
11
+ APPNAME,
12
+ SANDBOX_SUFFIX,
13
+ STRING_ENCODING,
14
+ InstanceType,
15
+ )
14
16
 
15
17
  from vantage6.cli.config import CliConfig
16
- from vantage6.cli.context import select_context_class
17
18
  from vantage6.cli.globals import CLICommandName
18
19
  from vantage6.cli.utils import validate_input_cmd_args
19
20
 
@@ -251,60 +252,6 @@ def get_running_servers(
251
252
  return [server.name for server in running_servers]
252
253
 
253
254
 
254
- def get_server_configuration_list(instance_type: InstanceType) -> None:
255
- """
256
- Print list of available server configurations.
257
-
258
- Parameters
259
- ----------
260
- instance_type : InstanceType
261
- The type of instance to get the configurations for
262
- """
263
- ctx_class = select_context_class(instance_type)
264
-
265
- running_server_names = find_running_service_names(instance_type)
266
- header = "\nName" + (21 * " ") + "Status" + (10 * " ") + "System/User"
267
-
268
- click.echo(header)
269
- click.echo("-" * len(header))
270
-
271
- running = Fore.GREEN + "Running" + Style.RESET_ALL
272
- stopped = Fore.RED + "Not running" + Style.RESET_ALL
273
-
274
- # system folders
275
- configs, failed_imports_system = ctx_class.available_configurations(
276
- system_folders=True
277
- )
278
- for config in configs:
279
- status = (
280
- running
281
- if f"{APPNAME}-{config.name}-system-{instance_type.value}"
282
- in running_server_names
283
- else stopped
284
- )
285
- click.echo(f"{config.name:25}{status:25} System ")
286
-
287
- # user folders
288
- configs, failed_imports_user = ctx_class.available_configurations(
289
- system_folders=False
290
- )
291
- for config in configs:
292
- status = (
293
- running
294
- if f"{APPNAME}-{config.name}-user-{instance_type.value}"
295
- in running_server_names
296
- else stopped
297
- )
298
- click.echo(f"{config.name:25}{status:25} User ")
299
-
300
- click.echo("-" * 85)
301
- if len(failed_imports_system) + len(failed_imports_user):
302
- warning(
303
- f"{Fore.RED}Failed imports: "
304
- f"{len(failed_imports_system) + len(failed_imports_user)}{Style.RESET_ALL}"
305
- )
306
-
307
-
308
255
  def print_log_worker(logs_stream: Iterable[bytes]) -> None:
309
256
  """
310
257
  Print the logs from the logs stream.
@@ -354,20 +301,6 @@ def get_config_name_from_service_name(service_name: str) -> str:
354
301
  return "-".join(service_name.split("-")[1:-2])
355
302
 
356
303
 
357
- def attach_logs(*labels: list[str]) -> None:
358
- """
359
- Attach to the logs of the given labels.
360
-
361
- Parameters
362
- ----------
363
- labels : list[str]
364
- The labels to attach to
365
- """
366
- command = ["kubectl", "logs", "--follow", "--selector", ",".join(labels)]
367
- process = Popen(command, stdout=None, stderr=None)
368
- process.wait()
369
-
370
-
371
304
  def get_main_cli_command_name(instance_type: InstanceType) -> str:
372
305
  """
373
306
  Get the main CLI command name for a given instance type.
@@ -419,7 +352,9 @@ def check_running(
419
352
  return helm_release_name in running_services
420
353
 
421
354
 
422
- def get_config_name_from_helm_release_name(helm_release_name: str) -> str:
355
+ def get_config_name_from_helm_release_name(
356
+ helm_release_name: str, is_store: bool = False
357
+ ) -> str:
423
358
  """
424
359
  Get the config name from a helm release name.
425
360
 
@@ -427,6 +362,8 @@ def get_config_name_from_helm_release_name(helm_release_name: str) -> str:
427
362
  ----------
428
363
  helm_release_name : str
429
364
  The name of the Helm release
365
+ is_store : bool, optional
366
+ Whether the instance is a store or not. By default False.
430
367
 
431
368
  Returns
432
369
  -------
@@ -436,4 +373,35 @@ def get_config_name_from_helm_release_name(helm_release_name: str) -> str:
436
373
  # helm release name is structured as:
437
374
  # f"{APPNAME}-{name}-{scope}-{instance_type}"
438
375
  # we want to get the name from the service name
439
- return "-".join(helm_release_name.split("-")[1:-2])
376
+ if is_store:
377
+ # for store, the instance type is `algorithm-store` which contains an additional
378
+ # hyphen
379
+ return "-".join(helm_release_name.split("-")[1:-3])
380
+ else:
381
+ return "-".join(helm_release_name.split("-")[1:-2])
382
+
383
+
384
+ def extract_name_and_is_sandbox(name: str | None, is_sandbox: bool) -> tuple[str, bool]:
385
+ """
386
+ Extract the name and is_sandbox from the name.
387
+
388
+ Note that the name may be None: this occurs before when this function is called
389
+ before the user has selected a name. This scenario is fine because when the user
390
+ selects a name interactively, the name never ends with the .sandbox suffix.
391
+
392
+ Parameters
393
+ ----------
394
+ name : str | None
395
+ The name of the instance
396
+ is_sandbox : bool
397
+ Whether the instance is a sandbox instance
398
+
399
+ Returns
400
+ -------
401
+ tuple[str, bool]
402
+ The name and is_sandbox
403
+ """
404
+ if name and name.endswith(SANDBOX_SUFFIX):
405
+ return name[: -len(SANDBOX_SUFFIX)], True
406
+ else:
407
+ return name, is_sandbox
@@ -0,0 +1,82 @@
1
+ from vantage6.common import error
2
+ from vantage6.common.globals import InstanceType
3
+
4
+ from vantage6.cli.common.utils import (
5
+ find_running_service_names,
6
+ get_config_name_from_helm_release_name,
7
+ select_context_and_namespace,
8
+ select_running_service,
9
+ )
10
+ from vantage6.cli.context import get_context
11
+ from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
12
+ from vantage6.cli.context.node import NodeContext
13
+ from vantage6.cli.context.server import ServerContext
14
+
15
+
16
+ def get_and_select_ctx(
17
+ instance_type: InstanceType,
18
+ name: str,
19
+ system_folders: bool,
20
+ context: str,
21
+ namespace: str,
22
+ is_sandbox: bool,
23
+ ) -> ServerContext | NodeContext | AlgorithmStoreContext:
24
+ """
25
+ Get and select the context for the given instance type.
26
+
27
+ Parameters
28
+ ----------
29
+ instance_type : InstanceType
30
+ The type of instance to get the context for
31
+ name : str
32
+ The name of the instance
33
+ system_folders : bool
34
+ Whether to use system folders or not
35
+ context : str
36
+ The Kubernetes context to use
37
+ namespace : str
38
+ The Kubernetes namespace to use
39
+ is_sandbox : bool
40
+ Whether the configuration is a sandbox configuration
41
+
42
+ Returns
43
+ -------
44
+ ServerContext | NodeContext | AlgorithmStoreContext
45
+ The context for the given instance type
46
+ """
47
+ context, namespace = select_context_and_namespace(
48
+ context=context,
49
+ namespace=namespace,
50
+ )
51
+ running_services = find_running_service_names(
52
+ instance_type=instance_type,
53
+ only_system_folders=False,
54
+ only_user_folders=False,
55
+ context=context,
56
+ namespace=namespace,
57
+ sandbox=is_sandbox,
58
+ )
59
+
60
+ if not running_services:
61
+ error(f"No running {instance_type.value}s found.")
62
+ exit(1)
63
+
64
+ if not name:
65
+ helm_name = select_running_service(running_services, instance_type)
66
+
67
+ service_name = get_config_name_from_helm_release_name(
68
+ helm_name, is_store=(instance_type == InstanceType.ALGORITHM_STORE)
69
+ )
70
+ ctx = get_context(
71
+ instance_type, service_name, system_folders, is_sandbox=is_sandbox
72
+ )
73
+
74
+ else:
75
+ ctx = get_context(instance_type, name, system_folders, is_sandbox=is_sandbox)
76
+ helm_name = ctx.helm_release_name
77
+ service_name = ctx.name
78
+
79
+ if helm_name not in running_services:
80
+ error(f"The {instance_type.value} {service_name} is not running.")
81
+ exit(1)
82
+ return ctx
@@ -1,3 +1,4 @@
1
+ from collections.abc import Callable
1
2
  from pathlib import Path
2
3
 
3
4
  import questionary as q
@@ -127,7 +128,7 @@ def _add_production_server_config(config: dict) -> dict:
127
128
 
128
129
 
129
130
  def make_configuration(
130
- config_producing_func: callable,
131
+ config_producing_func: Callable,
131
132
  config_producing_func_args: tuple,
132
133
  type_: InstanceType,
133
134
  instance_name: str,
@@ -139,7 +140,7 @@ def make_configuration(
139
140
 
140
141
  Parameters
141
142
  ----------
142
- config_producing_func : callable
143
+ config_producing_func : Callable
143
144
  Function to generate the configuration
144
145
  config_producing_func_args : tuple
145
146
  Arguments to pass to the config producing function
@@ -13,6 +13,7 @@ from colorama import Fore, Style
13
13
  from vantage6.common import error
14
14
  from vantage6.common.globals import InstanceType
15
15
 
16
+ from vantage6.cli.common.utils import extract_name_and_is_sandbox
16
17
  from vantage6.cli.context.algorithm_store import AlgorithmStoreContext
17
18
  from vantage6.cli.context.auth import AuthContext
18
19
  from vantage6.cli.context.node import NodeContext
@@ -74,6 +75,8 @@ def get_context(
74
75
  AppContext
75
76
  Specialized subclass context of AppContext for the given instance type
76
77
  """
78
+ name, is_sandbox = extract_name_and_is_sandbox(name, is_sandbox)
79
+
77
80
  ctx_class = select_context_class(type_)
78
81
  if not ctx_class.config_exists(name, system_folders, is_sandbox=is_sandbox):
79
82
  scope = "system" if system_folders else "user"
@@ -117,7 +117,7 @@ class AlgorithmStoreContext(BaseServerContext):
117
117
 
118
118
  @classmethod
119
119
  def available_configurations(
120
- cls, system_folders: bool = S_FOL
120
+ cls, system_folders: bool = S_FOL, is_sandbox: bool = False
121
121
  ) -> tuple[list, list]:
122
122
  """
123
123
  Find all available server configurations in the default folders.
@@ -134,5 +134,5 @@ class AlgorithmStoreContext(BaseServerContext):
134
134
  list contains invalid configuration files.
135
135
  """
136
136
  return super().available_configurations(
137
- InstanceType.ALGORITHM_STORE, system_folders
137
+ InstanceType.ALGORITHM_STORE, system_folders, is_sandbox
138
138
  )
@@ -2,13 +2,37 @@ import click
2
2
 
3
3
  from vantage6.common import info
4
4
 
5
- from vantage6.cli.common.utils import attach_logs
5
+ from vantage6.cli.common.attach import attach_logs
6
+ from vantage6.cli.context import InstanceType
7
+ from vantage6.cli.globals import InfraComponentName
6
8
 
7
9
 
8
10
  @click.command()
9
- def cli_node_attach() -> None:
11
+ @click.option("-n", "--name", default=None, help="Name of the configuration")
12
+ @click.option("--system", "system_folders", flag_value=True, help="Use system folders")
13
+ @click.option("--user", "system_folders", flag_value=False, help="Use user folders")
14
+ @click.option("--context", default=None, help="Kubernetes context to use")
15
+ @click.option("--namespace", default=None, help="Kubernetes namespace to use")
16
+ @click.option(
17
+ "--sandbox", "is_sandbox", flag_value=True, help="Attach to a sandbox environment"
18
+ )
19
+ def cli_node_attach(
20
+ name: str | None,
21
+ system_folders: bool,
22
+ context: str,
23
+ namespace: str,
24
+ is_sandbox: bool,
25
+ ) -> None:
10
26
  """
11
27
  Show the node logs in the current console.
12
28
  """
13
29
  info("Attaching to node logs...")
14
- attach_logs("app=node")
30
+ attach_logs(
31
+ name,
32
+ instance_type=InstanceType.NODE,
33
+ infra_component=InfraComponentName.NODE,
34
+ system_folders=system_folders,
35
+ context=context,
36
+ namespace=namespace,
37
+ is_sandbox=is_sandbox,
38
+ )
@@ -12,6 +12,7 @@ from vantage6.common.globals import (
12
12
  APPNAME,
13
13
  HTTP_LOCALHOST,
14
14
  InstanceType,
15
+ Ports,
15
16
  RequiredNodeEnvVars,
16
17
  )
17
18
 
@@ -21,6 +22,16 @@ from vantage6.cli.configuration_create import select_configuration_questionnaire
21
22
  from vantage6.cli.context.node import NodeContext
22
23
 
23
24
 
25
+ def _convert_k8s_url_to_localhost(url: str) -> str:
26
+ """
27
+ Convert a Kubernetes URL to a localhost URL.
28
+ """
29
+ if "svc.cluster.local" in url:
30
+ port_and_api_path = url.split(":")[-1]
31
+ return f"{HTTP_LOCALHOST}:{port_and_api_path}"
32
+ return url
33
+
34
+
24
35
  def create_client(ctx: NodeContext) -> UserClient:
25
36
  """
26
37
  Create a client instance.
@@ -34,17 +45,31 @@ def create_client(ctx: NodeContext) -> UserClient:
34
45
  UserClient
35
46
  vantage6 client
36
47
  """
37
- host = ctx.config["server_url"]
48
+ host = ctx.config["node"]["server"]["url"]
49
+ port = ctx.config["node"]["server"]["port"]
50
+ api_path = ctx.config["node"]["server"]["path"]
38
51
  # if the server is run locally, we need to use localhost here instead of
39
52
  # the host address of docker
40
53
  if host in ["http://host.docker.internal", "http://172.17.0.1"]:
41
54
  host = HTTP_LOCALHOST
42
- port = ctx.config["port"]
43
- api_path = ctx.config["api_path"]
44
- info(f"Connecting to server at '{host}:{port}{api_path}'")
55
+
56
+ url = f"{host}:{port}{api_path}"
57
+
58
+ auth_url = ctx.config.get("node", {}).get("keycloakUrl", None) or os.environ.get(
59
+ RequiredNodeEnvVars.KEYCLOAK_URL.value
60
+ )
61
+ # append the port to the auth URL as it is not included in the config
62
+ auth_url = f"{auth_url}:{Ports.DEV_AUTH.value}"
63
+
64
+ # if the server is a Kubernetes address, we need to use localhost because here
65
+ # we are connecting from the CLI outside the cluster
66
+ url = _convert_k8s_url_to_localhost(url)
67
+ auth_url = _convert_k8s_url_to_localhost(auth_url)
68
+
69
+ info(f"Connecting to server at '{url}' using auth URL '{auth_url}'")
45
70
  return UserClient(
46
- server_url=f"{host}:{port}{api_path}",
47
- auth_url=os.environ.get(RequiredNodeEnvVars.KEYCLOAK_URL.value),
71
+ server_url=url,
72
+ auth_url=auth_url,
48
73
  log_level="warn",
49
74
  )
50
75
 
@@ -11,10 +11,12 @@ from vantage6.common import (
11
11
  warning,
12
12
  )
13
13
  from vantage6.common.encryption import RSACryptor
14
+ from vantage6.common.globals import InstanceType
14
15
 
16
+ from vantage6.cli.configuration_create import select_configuration_questionnaire
15
17
  from vantage6.cli.context.node import NodeContext
16
18
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
17
- from vantage6.cli.node.common import create_client_and_authenticate, select_node
19
+ from vantage6.cli.node.common import create_client_and_authenticate
18
20
 
19
21
 
20
22
  @click.command()
@@ -80,12 +82,13 @@ def cli_node_create_private_key(
80
82
  if config:
81
83
  name = Path(config).stem
82
84
  ctx = NodeContext(name, system_folders, config)
83
- else:
84
- # retrieve context
85
- name = select_node(name, system_folders)
86
-
87
- # Create node context
88
- ctx = NodeContext(name, system_folders)
85
+ elif not name:
86
+ try:
87
+ name = select_configuration_questionnaire(InstanceType.NODE, system_folders)
88
+ except Exception:
89
+ error("No configurations could be found!")
90
+ exit(1)
91
+ ctx = NodeContext(name, system_folders)
89
92
 
90
93
  # Authenticate with the server to obtain organization name if it wasn't
91
94
  # provided
@@ -138,9 +141,7 @@ def cli_node_create_private_key(
138
141
 
139
142
  # update config file
140
143
  info("Updating configuration")
141
- # TODO v5+ this probably messes up the current config as the template is used...
142
- # Fix when reimplementing this in v5
143
- ctx.config["encryption"]["private_key"] = str(file_)
144
+ ctx.config["node"]["encryption"]["private_key"] = str(file_)
144
145
  ctx.config_manager.put(ctx.config)
145
146
  ctx.config_manager.save(ctx.config_file)
146
147
 
vantage6/cli/node/list.py CHANGED
@@ -1,13 +1,8 @@
1
1
  import click
2
- import docker
3
- from colorama import Fore, Style
4
2
 
5
- from vantage6.common import warning
6
- from vantage6.common.docker.addons import check_docker_running
7
- from vantage6.common.globals import APPNAME
3
+ from vantage6.common.globals import InstanceType
8
4
 
9
- from vantage6.cli.context.node import NodeContext
10
- from vantage6.cli.node.common import find_running_node_names
5
+ from vantage6.cli.common.list import get_configuration_list
11
6
 
12
7
 
13
8
  @click.command()
@@ -18,40 +13,4 @@ def cli_node_list() -> None:
18
13
  Note that this command cannot find node configuration files in custom
19
14
  directories.
20
15
  """
21
-
22
- check_docker_running()
23
- client = docker.from_env()
24
-
25
- running_node_names = find_running_node_names(client)
26
-
27
- header = "\nName" + (21 * " ") + "Status" + (10 * " ") + "System/User"
28
-
29
- click.echo(header)
30
- click.echo("-" * len(header))
31
-
32
- running = Fore.GREEN + "Running" + Style.RESET_ALL
33
- stopped = Fore.RED + "Not running" + Style.RESET_ALL
34
-
35
- # system folders
36
- configs, f1 = NodeContext.available_configurations(system_folders=True)
37
- for config in configs:
38
- status = (
39
- running
40
- if f"{APPNAME}-{config.name}-system" in running_node_names
41
- else stopped
42
- )
43
- click.echo(f"{config.name:25}{status:25}System ")
44
-
45
- # user folders
46
- configs, f2 = NodeContext.available_configurations(system_folders=False)
47
- for config in configs:
48
- status = (
49
- running
50
- if f"{APPNAME}-{config.name}-user" in running_node_names
51
- else stopped
52
- )
53
- click.echo(f"{config.name:25}{status:25}User ")
54
-
55
- click.echo("-" * 53)
56
- if len(f1) + len(f2):
57
- warning(f"{Fore.RED}Failed imports: {len(f1) + len(f2)}{Style.RESET_ALL}")
16
+ get_configuration_list(InstanceType.NODE)
@@ -2,11 +2,14 @@ import click
2
2
  import questionary as q
3
3
 
4
4
  from vantage6.common import ensure_config_dir_writable, error, info
5
+ from vantage6.common.globals import InstanceType
5
6
 
6
- from vantage6.cli.configuration_create import NodeConfigurationManager
7
+ from vantage6.cli.configuration_create import (
8
+ NodeConfigurationManager,
9
+ select_configuration_questionnaire,
10
+ )
7
11
  from vantage6.cli.context.node import NodeContext
8
12
  from vantage6.cli.globals import DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL
9
- from vantage6.cli.node.common import select_node
10
13
 
11
14
 
12
15
  @click.command()
@@ -31,7 +34,12 @@ def cli_node_set_api_key(name: str, api_key: str, system_folders: bool) -> None:
31
34
  Put a new API key into the node configuration file
32
35
  """
33
36
  # select node name
34
- name = select_node(name, system_folders)
37
+ if not name:
38
+ try:
39
+ name = select_configuration_questionnaire(InstanceType.NODE, system_folders)
40
+ except Exception:
41
+ error("No configurations could be found!")
42
+ exit(1)
35
43
 
36
44
  # Check that we can write in the config folder
37
45
  if not ensure_config_dir_writable(system_folders):
@@ -50,9 +58,7 @@ def cli_node_set_api_key(name: str, api_key: str, system_folders: bool) -> None:
50
58
  conf_mgr = NodeConfigurationManager.from_file(ctx.config_file)
51
59
 
52
60
  # set new api key, and save the file
53
- ctx.config["api_key"] = api_key
54
- # TODO v5+ this probably messes up the current config as the template is used...
55
- # Fix when reimplementing this in v5
61
+ ctx.config["node"]["apiKey"] = api_key
56
62
  conf_mgr.put(ctx.config)
57
63
  conf_mgr.save(ctx.config_file)
58
64
  info(f"Your new API key has been uploaded to the config file {ctx.config_file}.")
@@ -3,6 +3,7 @@ import click
3
3
  from vantage6.common import info
4
4
  from vantage6.common.globals import InstanceType
5
5
 
6
+ from vantage6.cli.common.attach import attach_logs
6
7
  from vantage6.cli.common.decorator import click_insert_context
7
8
  from vantage6.cli.common.start import (
8
9
  helm_install,
@@ -10,12 +11,11 @@ from vantage6.cli.common.start import (
10
11
  start_port_forward,
11
12
  )
12
13
  from vantage6.cli.common.utils import (
13
- attach_logs,
14
14
  create_directory_if_not_exists,
15
15
  select_context_and_namespace,
16
16
  )
17
17
  from vantage6.cli.context.node import NodeContext
18
- from vantage6.cli.globals import ChartName
18
+ from vantage6.cli.globals import ChartName, InfraComponentName
19
19
 
20
20
  from vantage6.node.globals import DEFAULT_PROXY_SERVER_PORT
21
21
 
@@ -123,4 +123,12 @@ def cli_node_start(
123
123
  )
124
124
 
125
125
  if attach:
126
- attach_logs("app=node")
126
+ attach_logs(
127
+ name,
128
+ instance_type=InstanceType.NODE,
129
+ infra_component=InfraComponentName.NODE,
130
+ system_folders=system_folders,
131
+ context=context,
132
+ namespace=namespace,
133
+ is_sandbox=ctx.is_sandbox,
134
+ )
vantage6/cli/node/stop.py CHANGED
@@ -1,20 +1,23 @@
1
1
  import click
2
- from kubernetes import client as k8s_client, config as k8s_config
2
+ from kubernetes import client as k8s_client
3
3
  from kubernetes.client import ApiException
4
- from kubernetes.config.config_exception import ConfigException
5
4
 
6
5
  from vantage6.common import error, info, warning
7
6
  from vantage6.common.globals import APPNAME, InstanceType
8
7
 
9
8
  from vantage6.cli.common.stop import execute_stop, helm_uninstall, stop_port_forward
10
- from vantage6.cli.common.utils import get_config_name_from_helm_release_name
9
+ from vantage6.cli.common.utils import (
10
+ extract_name_and_is_sandbox,
11
+ get_config_name_from_helm_release_name,
12
+ )
11
13
  from vantage6.cli.context import get_context
12
14
  from vantage6.cli.context.node import NodeContext
13
15
  from vantage6.cli.globals import (
14
16
  DEFAULT_NODE_SYSTEM_FOLDERS as N_FOL,
15
17
  InfraComponentName,
16
18
  )
17
- from vantage6.cli.node.task_cleanup import delete_job_related_pods
19
+ from vantage6.cli.node.common.task_cleanup import delete_job_related_pods
20
+ from vantage6.cli.utils_kubernetes import create_kubernetes_apis_with_ssl_handling
18
21
 
19
22
 
20
23
  @click.command()
@@ -50,6 +53,7 @@ def cli_node_stop(
50
53
  """
51
54
  Stop one or all running nodes.
52
55
  """
56
+ name, is_sandbox = extract_name_and_is_sandbox(name, is_sandbox)
53
57
  execute_stop(
54
58
  stop_function=_stop_node,
55
59
  stop_function_args={"system_folders": system_folders, "is_sandbox": is_sandbox},
@@ -142,18 +146,12 @@ def cleanup_task_jobs(
142
146
  error("Either all_nodes or node_ctx must be given to cleanup task jobs")
143
147
  return False
144
148
 
145
- # Load Kubernetes configuration (in-cluster first, fallback to kubeconfig)
149
+ # Load Kubernetes configuration with SSL handling
146
150
  try:
147
- k8s_config.load_incluster_config()
148
- except ConfigException:
149
- try:
150
- k8s_config.load_kube_config()
151
- except ConfigException as exc:
152
- error(f"Failed to load Kubernetes configuration: {exc}")
153
- return False
154
-
155
- core_api = k8s_client.CoreV1Api()
156
- batch_api = k8s_client.BatchV1Api()
151
+ core_api, batch_api = create_kubernetes_apis_with_ssl_handling()
152
+ except RuntimeError as exc:
153
+ error(f"Failed to load Kubernetes configuration: {exc}")
154
+ return False
157
155
 
158
156
  jobs = _get_jobs(namespace, batch_api)
159
157