outerbounds 0.8.0rc0__py3-none-any.whl → 0.8.0rc3__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.
- outerbounds/command_groups/workstations_cli.py +60 -12
- outerbounds/utils/ssh_utils.py +26 -6
- {outerbounds-0.8.0rc0.dist-info → outerbounds-0.8.0rc3.dist-info}/METADATA +1 -1
- {outerbounds-0.8.0rc0.dist-info → outerbounds-0.8.0rc3.dist-info}/RECORD +6 -6
- {outerbounds-0.8.0rc0.dist-info → outerbounds-0.8.0rc3.dist-info}/WHEEL +0 -0
- {outerbounds-0.8.0rc0.dist-info → outerbounds-0.8.0rc3.dist-info}/entry_points.txt +0 -0
@@ -598,7 +598,11 @@ def show_relevant_links(config_dir=None, profile=None, perimeter_id="", output="
|
|
598
598
|
click.secho("Error: {}".format(str(e)), fg="red", err=True)
|
599
599
|
|
600
600
|
|
601
|
-
|
601
|
+
WORKSTATION_CONNECT_MODE = "workstation-connect"
|
602
|
+
WORKSTATION_INIT_MODE = "workstation-init"
|
603
|
+
|
604
|
+
|
605
|
+
@cli.command(help="Prepare a workstation for SSH access", hidden=True)
|
602
606
|
@click.option(
|
603
607
|
"--workstation-id",
|
604
608
|
default="",
|
@@ -611,15 +615,55 @@ def show_relevant_links(config_dir=None, profile=None, perimeter_id="", output="
|
|
611
615
|
help="The context to use for the setup command",
|
612
616
|
type=click.Choice(["local", "remote"]),
|
613
617
|
)
|
614
|
-
|
618
|
+
@click.option(
|
619
|
+
"--output",
|
620
|
+
"-o",
|
621
|
+
default="",
|
622
|
+
help="Show output in the specified format.",
|
623
|
+
type=click.Choice(["json", ""]),
|
624
|
+
)
|
625
|
+
@click.option(
|
626
|
+
"--mode",
|
627
|
+
default="workstation-connect",
|
628
|
+
help="The mode in which the command is being run.",
|
629
|
+
type=click.Choice([WORKSTATION_CONNECT_MODE, WORKSTATION_INIT_MODE]),
|
630
|
+
)
|
631
|
+
def prepare_for_ssh_access(
|
632
|
+
workstation_id="", setup_context="", output="", mode=WORKSTATION_CONNECT_MODE
|
633
|
+
):
|
615
634
|
"""
|
616
635
|
Finds the pod whose WORKSTATION_NAME env var matches `workstation_name`
|
617
636
|
and opens an interactive bash shell in its "workstation" container.
|
618
637
|
"""
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
638
|
+
|
639
|
+
# Workstation Init is only supported on remote workstation.
|
640
|
+
if mode == WORKSTATION_INIT_MODE and setup_context == "local":
|
641
|
+
raise Exception("workstation-init mode is not supported for local setup")
|
642
|
+
|
643
|
+
response = {
|
644
|
+
"status": "OK",
|
645
|
+
"message": "SSH access prepared successfully",
|
646
|
+
}
|
647
|
+
try:
|
648
|
+
if setup_context == "local":
|
649
|
+
prepare_for_ssh_access_local(workstation_id)
|
650
|
+
elif setup_context == "remote":
|
651
|
+
prepare_for_ssh_access_remote(mode)
|
652
|
+
except Exception as e:
|
653
|
+
response["message"] = str(e)
|
654
|
+
response["status"] = "FAIL"
|
655
|
+
if output == "json":
|
656
|
+
click.echo(json.dumps(response, indent=4))
|
657
|
+
else:
|
658
|
+
click.secho(f"Failed to prepare for SSH access: {str(e)}", fg="red")
|
659
|
+
click.secho("Error: {}".format(str(e)), fg="red")
|
660
|
+
|
661
|
+
if output == "json":
|
662
|
+
click.echo(json.dumps(response, indent=4))
|
663
|
+
else:
|
664
|
+
click.secho(
|
665
|
+
f"SSH access prepared successfully: {response['message']}", fg="green"
|
666
|
+
)
|
623
667
|
|
624
668
|
|
625
669
|
def prepare_for_ssh_access_local(workstation_id):
|
@@ -672,7 +716,7 @@ def prepare_for_ssh_access_local(workstation_id):
|
|
672
716
|
raise Exception(f"Failed to add entry to ssh config: {msg}")
|
673
717
|
|
674
718
|
|
675
|
-
def prepare_for_ssh_access_remote():
|
719
|
+
def prepare_for_ssh_access_remote(mode: str):
|
676
720
|
"""
|
677
721
|
SSH connection requires both local instance and workstation pod to do some work.
|
678
722
|
This function takes care of the remote instance.
|
@@ -685,16 +729,20 @@ def prepare_for_ssh_access_remote():
|
|
685
729
|
if "WORKSTATION_ID" not in os.environ:
|
686
730
|
raise Exception("This can only be run from a workstation!")
|
687
731
|
|
688
|
-
ok, message = ssh_utils.
|
732
|
+
ok, message = ssh_utils.best_effort_install_remote_deps()
|
689
733
|
if not ok:
|
690
|
-
raise Exception(f"Failed to install
|
734
|
+
raise Exception(f"Failed to install deps in remote instance: {message}")
|
691
735
|
|
692
736
|
ok, msg = ssh_utils.configure_ssh_server()
|
693
737
|
if not ok:
|
694
738
|
raise Exception(f"Failed to configure ssh server: {msg}")
|
695
739
|
|
696
|
-
|
697
|
-
if
|
698
|
-
|
740
|
+
# SSH keys can only be guaranteed to be present when a connection is initiated.
|
741
|
+
if mode == WORKSTATION_CONNECT_MODE:
|
742
|
+
ok, msg = ssh_utils.ensure_public_key_registered_in_ssh_agent()
|
743
|
+
if not ok:
|
744
|
+
raise Exception(
|
745
|
+
f"Failed to ensure public key registered in ssh agent: {msg}"
|
746
|
+
)
|
699
747
|
|
700
748
|
ssh_utils.add_env_loader_to_bashrc()
|
outerbounds/utils/ssh_utils.py
CHANGED
@@ -318,7 +318,7 @@ fi
|
|
318
318
|
return False
|
319
319
|
|
320
320
|
|
321
|
-
def
|
321
|
+
def best_effort_install_remote_deps():
|
322
322
|
"""
|
323
323
|
Best effort installation of openssh-server and netcat.
|
324
324
|
|
@@ -369,42 +369,49 @@ def best_effort_install_ssh_netcat():
|
|
369
369
|
"install": "apt-get install -y",
|
370
370
|
"ssh_package": "openssh-server",
|
371
371
|
"nc_packages": ["netcat-openbsd", "netcat-traditional", "netcat"],
|
372
|
+
"curl_package": "curl",
|
372
373
|
},
|
373
374
|
"apt": {
|
374
375
|
"update": "apt update",
|
375
376
|
"install": "apt install -y",
|
376
377
|
"ssh_package": "openssh-server",
|
377
378
|
"nc_packages": ["netcat-openbsd", "netcat-traditional", "netcat"],
|
379
|
+
"curl_package": "curl",
|
378
380
|
},
|
379
381
|
"yum": {
|
380
382
|
"update": "yum makecache",
|
381
383
|
"install": "yum install -y",
|
382
384
|
"ssh_package": "openssh-server",
|
383
385
|
"nc_packages": ["nmap-ncat", "nc", "netcat"],
|
386
|
+
"curl_package": "curl",
|
384
387
|
},
|
385
388
|
"dnf": {
|
386
389
|
"update": "dnf makecache",
|
387
390
|
"install": "dnf install -y",
|
388
391
|
"ssh_package": "openssh-server",
|
389
392
|
"nc_packages": ["nmap-ncat", "nc", "netcat"],
|
393
|
+
"curl_package": "curl",
|
390
394
|
},
|
391
395
|
"zypper": {
|
392
396
|
"update": "zypper refresh",
|
393
397
|
"install": "zypper install -n",
|
394
398
|
"ssh_package": "openssh",
|
395
399
|
"nc_packages": ["netcat-openbsd", "gnu-netcat", "netcat"],
|
400
|
+
"curl_package": "curl",
|
396
401
|
},
|
397
402
|
"pacman": {
|
398
403
|
"update": "pacman -Sy",
|
399
404
|
"install": "pacman -S --noconfirm",
|
400
405
|
"ssh_package": "openssh",
|
401
406
|
"nc_packages": ["gnu-netcat", "openbsd-netcat"],
|
407
|
+
"curl_package": "curl",
|
402
408
|
},
|
403
409
|
"apk": {
|
404
410
|
"update": "apk update",
|
405
411
|
"install": "apk add --no-cache",
|
406
412
|
"ssh_package": "openssh-server",
|
407
|
-
"nc_packages": ["netcat-openbsd"
|
413
|
+
"nc_packages": ["netcat-openbsd"],
|
414
|
+
"curl_package": "curl",
|
408
415
|
},
|
409
416
|
}
|
410
417
|
|
@@ -431,9 +438,10 @@ def best_effort_install_ssh_netcat():
|
|
431
438
|
or check_command_exists("netcat")
|
432
439
|
or check_command_exists("ncat")
|
433
440
|
)
|
441
|
+
curl_installed = check_command_exists("curl")
|
434
442
|
|
435
|
-
if ssh_installed and nc_installed:
|
436
|
-
return True, "
|
443
|
+
if ssh_installed and nc_installed and curl_installed:
|
444
|
+
return True, "openssh-server, netcat, and curl are already installed"
|
437
445
|
|
438
446
|
# Prepare status messages
|
439
447
|
status = []
|
@@ -441,6 +449,8 @@ def best_effort_install_ssh_netcat():
|
|
441
449
|
status.append("openssh-server is already installed")
|
442
450
|
if nc_installed:
|
443
451
|
status.append("netcat is already installed")
|
452
|
+
if curl_installed:
|
453
|
+
status.append("curl is already installed")
|
444
454
|
|
445
455
|
# Step 2 & 3: Check sudo availability and access
|
446
456
|
has_sudo = check_command_exists("sudo")
|
@@ -504,6 +514,15 @@ def best_effort_install_ssh_netcat():
|
|
504
514
|
or check_command_exists("ncat")
|
505
515
|
)
|
506
516
|
|
517
|
+
# Install curl if needed
|
518
|
+
if not curl_installed:
|
519
|
+
curl_package = pm_config["curl_package"]
|
520
|
+
if install_package(curl_package, pm_config, use_sudo):
|
521
|
+
status.append(f"Successfully installed {curl_package}")
|
522
|
+
curl_installed = check_command_exists("curl")
|
523
|
+
else:
|
524
|
+
status.append(f"Failed to install {curl_package}")
|
525
|
+
|
507
526
|
# Step 7: Final check and return appropriate message
|
508
527
|
ssh_final = check_ssh_server()
|
509
528
|
nc_final = (
|
@@ -511,10 +530,11 @@ def best_effort_install_ssh_netcat():
|
|
511
530
|
or check_command_exists("netcat")
|
512
531
|
or check_command_exists("ncat")
|
513
532
|
)
|
533
|
+
curl_final = check_command_exists("curl")
|
514
534
|
|
515
|
-
if ssh_final and nc_final:
|
535
|
+
if ssh_final and nc_final and curl_final:
|
516
536
|
return True, "Successfully installed all required packages. " + " ".join(status)
|
517
|
-
elif ssh_final or nc_final:
|
537
|
+
elif ssh_final or nc_final or curl_final:
|
518
538
|
installed = []
|
519
539
|
missing = []
|
520
540
|
if ssh_final:
|
@@ -51,16 +51,16 @@ outerbounds/command_groups/local_setup_cli.py,sha256=tuuqJRXQ_guEwOuQSIf9wkUU0yg
|
|
51
51
|
outerbounds/command_groups/perimeters_cli.py,sha256=iF_Uw7ROiSctf6FgoJEy30iDBLVE1j9FKuR3shgJRmc,19050
|
52
52
|
outerbounds/command_groups/secrets_cli.py,sha256=Vgn_aiTo76a0s5hCJhNWEOrCVhyYeivD08ooQxz0y7c,2952
|
53
53
|
outerbounds/command_groups/tutorials_cli.py,sha256=UInFyiMqtscHFfi8YQwiY_6Sdw9quJOtRu5OukEBccw,3522
|
54
|
-
outerbounds/command_groups/workstations_cli.py,sha256
|
54
|
+
outerbounds/command_groups/workstations_cli.py,sha256=-VFJqIvi_jcHcydaMLj8EaZ-Lbe-yBukkd9QCKrH5f0,27201
|
55
55
|
outerbounds/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
56
|
outerbounds/utils/kubeconfig.py,sha256=yvcyRXGR4AhQuqUDqmbGxEOHw5ixMFV0AZIDg1LI_Qo,7981
|
57
57
|
outerbounds/utils/kubectl_utils.py,sha256=y01xZ2AGW3CCnCbX7t9pfrhWsR9pDAyzlYiKdnZ-CK8,1916
|
58
58
|
outerbounds/utils/metaflowconfig.py,sha256=l2vJbgPkLISU-XPGZFaC8ZKmYFyJemlD6bwB-EKUsAw,5770
|
59
59
|
outerbounds/utils/schema.py,sha256=lMUr9kNgn9wy-sO_t_Tlxmbt63yLeN4b0xQXbDUDj4A,2331
|
60
|
-
outerbounds/utils/ssh_utils.py,sha256=
|
60
|
+
outerbounds/utils/ssh_utils.py,sha256=MRJ7Oy0M7Lqqs397JDJczTYvxvyHJ_XvBdjt4ZYKaPE,19599
|
61
61
|
outerbounds/utils/utils.py,sha256=4Z8cszNob_8kDYCLNTrP-wWads_S_MdL3Uj3ju4mEsk,501
|
62
62
|
outerbounds/vendor.py,sha256=gRLRJNXtZBeUpPEog0LOeIsl6GosaFFbCxUvR4bW6IQ,5093
|
63
|
-
outerbounds-0.8.
|
64
|
-
outerbounds-0.8.
|
65
|
-
outerbounds-0.8.
|
66
|
-
outerbounds-0.8.
|
63
|
+
outerbounds-0.8.0rc3.dist-info/METADATA,sha256=XMtUoeg6yt2zrgiGZhgJ7t5FJ90ovnVid4i4jn3NudU,1825
|
64
|
+
outerbounds-0.8.0rc3.dist-info/entry_points.txt,sha256=AP6rZg7y5SK9e9a9iVq0Fi9Q2KPjPZSwtZ6R98rLw-8,56
|
65
|
+
outerbounds-0.8.0rc3.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
66
|
+
outerbounds-0.8.0rc3.dist-info/RECORD,,
|
File without changes
|
File without changes
|