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.
@@ -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
- @cli.command(help="Prepare a workstation for SSH access")
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
- def prepare_for_ssh_access(workstation_id="", setup_context=""):
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
- if setup_context == "local":
620
- prepare_for_ssh_access_local(workstation_id)
621
- elif setup_context == "remote":
622
- prepare_for_ssh_access_remote()
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.best_effort_install_ssh_netcat()
732
+ ok, message = ssh_utils.best_effort_install_remote_deps()
689
733
  if not ok:
690
- raise Exception(f"Failed to install ssh and netcat: {message}")
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
- ok, msg = ssh_utils.ensure_public_key_registered_in_ssh_agent()
697
- if not ok:
698
- raise Exception(f"Failed to ensure public key registered in ssh agent: {msg}")
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()
@@ -318,7 +318,7 @@ fi
318
318
  return False
319
319
 
320
320
 
321
- def best_effort_install_ssh_netcat():
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", "busybox"],
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, "Both openssh-server and netcat are already installed"
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: outerbounds
3
- Version: 0.8.0rc0
3
+ Version: 0.8.0rc3
4
4
  Summary: More Data Science, Less Administration
5
5
  License: Proprietary
6
6
  Keywords: data science,machine learning,MLOps
@@ -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=GARk9r0ulsoNQytYxHipnWmUHprZSyd-b0ZZFHO2BOE,25631
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=A6rgi307DmBTdhDj7V7Tm-OYgMj2xRyx770t2FKs9uw,18737
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.0rc0.dist-info/METADATA,sha256=fMzhxYpFyR-dUkbMw5AsEoiepHwWVwlnB-_0CsrFs7U,1825
64
- outerbounds-0.8.0rc0.dist-info/entry_points.txt,sha256=AP6rZg7y5SK9e9a9iVq0Fi9Q2KPjPZSwtZ6R98rLw-8,56
65
- outerbounds-0.8.0rc0.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
66
- outerbounds-0.8.0rc0.dist-info/RECORD,,
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,,