dayhoff-tools 1.1.16__py3-none-any.whl → 1.1.18__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.
@@ -902,6 +902,72 @@ def gcp_use_devcon_adc():
902
902
  sys.exit(1)
903
903
 
904
904
 
905
+ @gcp_app.command("logout")
906
+ def gcp_logout():
907
+ """Clear all GCP credentials for testing or role switching purposes.
908
+
909
+ This removes the active user's gcloud login, disables impersonation,
910
+ and invalidates Application Default Credentials (ADC).
911
+ """
912
+ print(f"{BLUE}Clearing all GCP credentials...{NC}")
913
+
914
+ try:
915
+ gcloud_path = _find_executable("gcloud")
916
+ errors = []
917
+
918
+ # 1. Revoke user-level credentials
919
+ print(f"{BLUE}Revoking active gcloud credentials...{NC}")
920
+ revoke_cmd = [gcloud_path, "auth", "revoke", "--all", "--quiet"]
921
+ revoke_code, _, revoke_err = _run_command(revoke_cmd, capture=True, check=False)
922
+ if revoke_code != 0 and revoke_err:
923
+ errors.append(f"Failed to revoke credentials: {revoke_err}")
924
+
925
+ # 2. Unset impersonation config
926
+ print(f"{BLUE}Disabling service account impersonation...{NC}")
927
+ unset_code, _, unset_err = _gcloud_unset_config(
928
+ "auth/impersonate_service_account"
929
+ )
930
+ if unset_code != 0 and unset_err:
931
+ errors.append(f"Failed to unset impersonation: {unset_err}")
932
+
933
+ # 3. Revoke ADC
934
+ print(f"{BLUE}Revoking Application Default Credentials (ADC)...{NC}")
935
+ adc_cmd = [gcloud_path, "auth", "application-default", "revoke", "--quiet"]
936
+ adc_code, _, adc_err = _run_command(adc_cmd, capture=True, check=False)
937
+
938
+ # 4. Additionally remove ADC file if it exists (belt-and-suspenders approach)
939
+ adc_file = (
940
+ Path.home() / ".config" / "gcloud" / "application_default_credentials.json"
941
+ )
942
+ if adc_file.exists():
943
+ try:
944
+ adc_file.unlink()
945
+ print(f"{BLUE}Removed ADC file: {adc_file}{NC}")
946
+ except Exception as e:
947
+ errors.append(f"Failed to delete ADC file: {e}")
948
+
949
+ if errors:
950
+ print(f"{YELLOW}Logged out with some warnings:{NC}")
951
+ for err in errors:
952
+ print(f"{YELLOW} - {err}{NC}")
953
+ else:
954
+ print(f"{GREEN}Successfully logged out from GCP.{NC}")
955
+
956
+ # Always show how to log back in
957
+ print(f"\n{BLUE}To log back in:{NC}")
958
+ print(f" {YELLOW}dh gcp login{NC}")
959
+
960
+ # Show current (now-cleared) status
961
+ print(f"\n{BLUE}Current status:{NC}")
962
+ gcp_status()
963
+
964
+ except Exception as e:
965
+ print(f"{RED}Error during logout: {e}{NC}", file=sys.stderr)
966
+ print(f"{YELLOW}You may need to manually run:{NC}")
967
+ print(f" {YELLOW}gcloud auth revoke --all{NC}")
968
+ print(f" {YELLOW}gcloud auth application-default revoke{NC}")
969
+
970
+
905
971
  # === End NEW ADC Commands ===
906
972
 
907
973
 
dayhoff_tools/cli/main.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Entry file for the CLI, which aggregates and aliases all commands."""
2
2
 
3
+ import sys
4
+
3
5
  import typer
4
6
  from dayhoff_tools.cli.cloud_commands import aws_app, gcp_app
5
7
  from dayhoff_tools.cli.utility_commands import (
@@ -96,6 +98,24 @@ def deploy_command(
96
98
  config_path: str = typer.Argument(help="Path to the YAML configuration file"),
97
99
  ):
98
100
  """Unified deployment command."""
101
+ # Check GCP credentials if deploying in batch mode with GCP
102
+ # Do this early to fail fast before importing deployment code
103
+ if mode == "batch":
104
+ try:
105
+ # Check cloud provider in config
106
+ import yaml
107
+
108
+ with open(config_path, "r") as f:
109
+ config = yaml.safe_load(f)
110
+
111
+ if config.get("cloud") == "gcp":
112
+ from dayhoff_tools.cli.utility_commands import _warn_if_gcp_default_sa
113
+
114
+ _warn_if_gcp_default_sa(force_prompt=True)
115
+ except Exception as e:
116
+ # Don't block deployment if config can't be read or other errors occur
117
+ print(f"Warning: Could not check GCP credentials: {e}", file=sys.stderr)
118
+
99
119
  from dayhoff_tools.deployment.base import deploy
100
120
 
101
121
  deploy(mode, config_path)
@@ -394,6 +394,50 @@ def deploy(
394
394
  get_boto_session(config)
395
395
  print("AWS credentials verified.")
396
396
 
397
+ # Check GCP credentials early if using GCP
398
+ elif cloud == "gcp":
399
+ print("\nVerifying GCP credentials...")
400
+ from dayhoff_tools.cli.cloud_commands import (
401
+ _is_adc_authenticated,
402
+ _is_gcp_user_authenticated,
403
+ )
404
+
405
+ user_creds_valid = _is_gcp_user_authenticated()
406
+ adc_creds_valid = _is_adc_authenticated()
407
+
408
+ if not user_creds_valid:
409
+ print(
410
+ "\n⚠️ Warning: Your GCP user credentials appear to be stale/expired."
411
+ )
412
+ print(
413
+ " This may cause authentication issues when deploying to GCP Batch."
414
+ )
415
+ print(" Consider running 'dh gcp login' to refresh your credentials.")
416
+
417
+ if not adc_creds_valid:
418
+ print(
419
+ "\n⚠️ Warning: Your Application Default Credentials (ADC) appear to be stale/expired."
420
+ )
421
+ print(
422
+ " This may cause authentication issues with API client libraries."
423
+ )
424
+ print(
425
+ " Consider running 'dh gcp use-user-adc' or 'dh gcp use-devcon-adc' to refresh your ADC."
426
+ )
427
+
428
+ if user_creds_valid and adc_creds_valid:
429
+ print("GCP credentials verified.")
430
+ else:
431
+ # Ask for confirmation before proceeding with possibly invalid credentials
432
+ proceed = (
433
+ input("\nProceed with potentially invalid credentials? (y/n): ")
434
+ .lower()
435
+ .strip()
436
+ )
437
+ if proceed != "y":
438
+ print("Deployment aborted.")
439
+ return
440
+
397
441
  # Track if we built a new image
398
442
  had_image_uri = bool(config["docker"]["image_uri"])
399
443
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.1.16
3
+ Version: 1.1.18
4
4
  Summary: Common tools for all the repos at Dayhoff Labs
5
5
  Author: Daniel Martin-Alarcon
6
6
  Author-email: dma@dayhofflabs.com
@@ -2,11 +2,11 @@ dayhoff_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  dayhoff_tools/chemistry/standardizer.py,sha256=uMn7VwHnx02nc404eO6fRuS4rsl4dvSPf2ElfZDXEpY,11188
3
3
  dayhoff_tools/chemistry/utils.py,sha256=jt-7JgF-GeeVC421acX-bobKbLU_X94KNOW24p_P-_M,2257
4
4
  dayhoff_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- dayhoff_tools/cli/cloud_commands.py,sha256=ekUD2B6kL335ZMrP00I-tKD0qMgSMBWdR-WJRzwJRFY,38182
6
- dayhoff_tools/cli/main.py,sha256=Ae0Bee2VjRzUge1I2DJoDVqoXpQnKfxGhdiMSmIWJwo,3788
5
+ dayhoff_tools/cli/cloud_commands.py,sha256=NGux28-cjDyCADF-L1tjdEMzkCMYX8V4xNvpK6EWcZA,40802
6
+ dayhoff_tools/cli/main.py,sha256=47EGb28ALaYFc7oAUGlY1D66AIDmc4RZiXxN-gPVrpQ,4519
7
7
  dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
8
8
  dayhoff_tools/cli/utility_commands.py,sha256=PRShdh4O35JfjVxTOsduZ8-grGF5-SfXihcptcFT-hk,23584
9
- dayhoff_tools/deployment/base.py,sha256=u-AjbtHnFLoLt33dhYXHIpV-6jcieMEHHGBGN_U9Hm0,15626
9
+ dayhoff_tools/deployment/base.py,sha256=8tXwsPYvRo-zV-aNhHw1c7Rji-KWg8S5xoCCznFnVVI,17412
10
10
  dayhoff_tools/deployment/deploy_aws.py,sha256=O0gQxHioSU_sNU8T8MD4wSOPvWc--V8eRRZzlRu035I,16446
11
11
  dayhoff_tools/deployment/deploy_gcp.py,sha256=DxBM4sUzwPK9RWLP9bSfr38n1HHl-TVrp4TsbdN8pUA,5795
12
12
  dayhoff_tools/deployment/deploy_utils.py,sha256=StFwbqnr2_FWiKVg3xnJF4kagTHzndqqDkpaIOaAn_4,26027
@@ -26,7 +26,7 @@ dayhoff_tools/intake/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJq
26
26
  dayhoff_tools/logs.py,sha256=DKdeP0k0kliRcilwvX0mUB2eipO5BdWUeHwh-VnsICs,838
27
27
  dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
28
28
  dayhoff_tools/warehouse.py,sha256=TqV8nex1AluNaL4JuXH5zuu9P7qmE89lSo6f_oViy6U,14965
29
- dayhoff_tools-1.1.16.dist-info/METADATA,sha256=R7gtNrSoRE5dq3m7_eQHu-u9ztkzzPWtvT-xl8ajvhE,2225
30
- dayhoff_tools-1.1.16.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
31
- dayhoff_tools-1.1.16.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
32
- dayhoff_tools-1.1.16.dist-info/RECORD,,
29
+ dayhoff_tools-1.1.18.dist-info/METADATA,sha256=9uJXFcLDGpuxssU_xBvmehDR58gPs-gFtKShHhEw4u4,2225
30
+ dayhoff_tools-1.1.18.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
31
+ dayhoff_tools-1.1.18.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
32
+ dayhoff_tools-1.1.18.dist-info/RECORD,,