cloudx-proxy 0.4.5__py3-none-any.whl → 0.4.6__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.
cloudx_proxy/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4.5'
21
- __version_tuple__ = version_tuple = (0, 4, 5)
20
+ __version__ = version = '0.4.6'
21
+ __version_tuple__ = version_tuple = (0, 4, 6)
cloudx_proxy/cli.py CHANGED
@@ -55,7 +55,10 @@ def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str
55
55
  @click.option('--ssh-config', help='SSH config file to use (default: ~/.ssh/vscode/config)')
56
56
  @click.option('--aws-env', help='AWS environment directory (default: ~/.aws, use name of directory in ~/.aws/aws-envs/)')
57
57
  @click.option('--1password', 'use_1password', is_flag=True, help='Use 1Password SSH agent for SSH authentication')
58
- def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1password: bool):
58
+ @click.option('--instance', help='EC2 instance ID to set up connection for')
59
+ @click.option('--yes', 'non_interactive', is_flag=True, help='Non-interactive mode, use default values for all prompts')
60
+ def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1password: bool,
61
+ instance: str, non_interactive: bool):
59
62
  """Set up AWS profile, SSH keys, and configuration for CloudX.
60
63
 
61
64
  This command will:
@@ -69,6 +72,7 @@ def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1passwo
69
72
  cloudx-proxy setup --profile myprofile --ssh-key mykey
70
73
  cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config
71
74
  cloudx-proxy setup --1password
75
+ cloudx-proxy setup --instance i-0123456789abcdef0 --yes
72
76
  """
73
77
  try:
74
78
  setup = CloudXSetup(
@@ -76,7 +80,9 @@ def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1passwo
76
80
  ssh_key=ssh_key,
77
81
  ssh_config=ssh_config,
78
82
  aws_env=aws_env,
79
- use_1password=use_1password
83
+ use_1password=use_1password,
84
+ instance_id=instance,
85
+ non_interactive=non_interactive
80
86
  )
81
87
 
82
88
  print("\n\033[1;95m=== cloudx-proxy Setup ===\033[0m\n")
@@ -91,8 +97,13 @@ def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1passwo
91
97
 
92
98
  # Get environment and instance details
93
99
  cloudx_env = setup.prompt("Enter environment", getattr(setup, 'default_env', None))
94
- instance_id = setup.prompt("Enter EC2 instance ID (e.g., i-0123456789abcdef0)")
95
- hostname = setup.prompt("Enter hostname for the instance")
100
+
101
+ # Use the --instance parameter if provided, otherwise prompt
102
+ instance_id = instance or setup.prompt("Enter EC2 instance ID (e.g., i-0123456789abcdef0)")
103
+
104
+ # Generate a default hostname based on instance ID if we're in non-interactive mode
105
+ hostname_default = f"instance-{instance_id[-7:]}" if non_interactive else None
106
+ hostname = setup.prompt("Enter hostname for the instance", hostname_default)
96
107
 
97
108
  # Set up SSH config
98
109
  if not setup.setup_ssh_config(cloudx_env, instance_id, hostname):
cloudx_proxy/setup.py CHANGED
@@ -10,8 +10,12 @@ from botocore.exceptions import ClientError
10
10
  from ._1password import check_1password_cli, check_ssh_agent, list_ssh_keys, create_ssh_key, get_vaults, save_public_key
11
11
 
12
12
  class CloudXSetup:
13
+ # Define SSH key prefix as a constant
14
+ SSH_KEY_PREFIX = "cloudX SSH Key - "
15
+
13
16
  def __init__(self, profile: str = "vscode", ssh_key: str = "vscode", ssh_config: str = None,
14
- aws_env: str = None, use_1password: bool = False):
17
+ aws_env: str = None, use_1password: bool = False, instance_id: str = None,
18
+ non_interactive: bool = False):
15
19
  """Initialize cloudx-proxy setup.
16
20
 
17
21
  Args:
@@ -20,11 +24,15 @@ class CloudXSetup:
20
24
  ssh_config: SSH config file path (default: None, uses ~/.ssh/vscode/config)
21
25
  aws_env: AWS environment directory (default: None)
22
26
  use_1password: Use 1Password SSH agent for authentication (default: False)
27
+ instance_id: EC2 instance ID to set up connection for (optional)
28
+ non_interactive: Non-interactive mode, use defaults for all prompts (default: False)
23
29
  """
24
30
  self.profile = profile
25
31
  self.ssh_key = ssh_key
26
32
  self.aws_env = aws_env
27
33
  self.use_1password = use_1password
34
+ self.instance_id = instance_id
35
+ self.non_interactive = non_interactive
28
36
  self.home_dir = str(Path.home())
29
37
  self.onepassword_agent_sock = Path(self.home_dir) / ".1password" / "agent.sock"
30
38
 
@@ -74,6 +82,16 @@ class CloudXSetup:
74
82
  Returns:
75
83
  str: User's input or default value
76
84
  """
85
+ # In non-interactive mode, always use the default value
86
+ if self.non_interactive:
87
+ if default:
88
+ self.print_status(f"{message}: Using default [{default}]", None, 2)
89
+ return default
90
+ else:
91
+ self.print_status(f"{message}: No default value available", False, 2)
92
+ raise ValueError(f"Non-interactive mode requires default value for: {message}")
93
+
94
+ # Interactive prompt
77
95
  if default:
78
96
  prompt_text = f"\033[93m{message} [{default}]: \033[0m"
79
97
  else:
@@ -200,38 +218,14 @@ class CloudXSetup:
200
218
  bool: True if successful
201
219
  """
202
220
  try:
203
- # Get vaults to determine where to store the key
204
- vaults = get_vaults()
205
- if not vaults:
206
- self.print_status("No 1Password vaults found", False, 2)
207
- return False
208
-
209
- # Display available vaults
210
- self.print_status("Creating a new SSH key in 1Password", None, 2)
211
- print("\n\033[96mAvailable 1Password vaults:\033[0m")
212
- for i, vault in enumerate(vaults):
213
- print(f" {i+1}. {vault['name']}")
214
-
215
- # Let user select vault
216
- vault_num = self.prompt("Select vault number to store SSH key", "1")
217
- try:
218
- vault_idx = int(vault_num) - 1
219
- if vault_idx < 0 or vault_idx >= len(vaults):
220
- self.print_status("Invalid vault number", False, 2)
221
- return False
222
- selected_vault = vaults[vault_idx]['id']
223
- except ValueError:
224
- self.print_status("Invalid input", False, 2)
225
- return False
226
-
227
221
  # Create possible title variations for the 1Password item
228
- ssh_key_title_with_prefix = f"cloudX SSH Key - {self.ssh_key}"
222
+ ssh_key_title_with_prefix = f"{self.SSH_KEY_PREFIX}{self.ssh_key}"
229
223
  ssh_key_title_without_prefix = self.ssh_key
230
224
 
231
- # Check if a key with either title exists in 1Password
225
+ # First check if key exists in any vault
232
226
  ssh_keys = list_ssh_keys()
233
227
 
234
- # First check for our prefixed format, then for a plain key with the same name
228
+ # Check for both prefixed and non-prefixed format
235
229
  existing_key = next((key for key in ssh_keys if key['title'] == ssh_key_title_with_prefix), None)
236
230
  if not existing_key:
237
231
  existing_key = next((key for key in ssh_keys if key['title'] == ssh_key_title_without_prefix), None)
@@ -253,25 +247,56 @@ class CloudXSetup:
253
247
  if save_public_key(public_key, f"{self.ssh_key_file}.pub"):
254
248
  self.print_status(f"Saved existing public key to {self.ssh_key_file}.pub", True, 2)
255
249
  return True
256
- else:
257
- # Create a new SSH key in 1Password
258
- self.print_status(f"Creating new SSH key '{ssh_key_title_with_prefix}' in 1Password...", None, 2)
259
- success, public_key, item_id = create_ssh_key(ssh_key_title_with_prefix, selected_vault)
260
-
261
- if not success:
262
- self.print_status("Failed to create SSH key in 1Password", False, 2)
263
- return False
264
-
265
- self.print_status("SSH key created successfully in 1Password", True, 2)
266
-
267
- # Save the public key to the expected location
268
- if save_public_key(public_key, f"{self.ssh_key_file}.pub"):
269
- self.print_status(f"Saved public key to {self.ssh_key_file}.pub", True, 2)
270
- return True
250
+ else:
251
+ self.print_status(f"Failed to save public key to {self.ssh_key_file}.pub", False, 2)
252
+ return False
271
253
  else:
272
- self.print_status(f"Failed to save public key to {self.ssh_key_file}.pub", False, 2)
254
+ self.print_status(f"Failed to retrieve public key from 1Password", False, 2)
273
255
  return False
274
256
 
257
+ # If we reach here, the key doesn't exist and we need to create it
258
+ # Get vaults to determine where to store the key
259
+ vaults = get_vaults()
260
+ if not vaults:
261
+ self.print_status("No 1Password vaults found", False, 2)
262
+ return False
263
+
264
+ # Display available vaults
265
+ self.print_status("Creating a new SSH key in 1Password", None, 2)
266
+ print("\n\033[96mAvailable 1Password vaults:\033[0m")
267
+ for i, vault in enumerate(vaults):
268
+ print(f" {i+1}. {vault['name']}")
269
+
270
+ # Let user select vault
271
+ vault_num = self.prompt("Select vault number to store SSH key", "1")
272
+ try:
273
+ vault_idx = int(vault_num) - 1
274
+ if vault_idx < 0 or vault_idx >= len(vaults):
275
+ self.print_status("Invalid vault number", False, 2)
276
+ return False
277
+ selected_vault = vaults[vault_idx]['id']
278
+ except ValueError:
279
+ self.print_status("Invalid input", False, 2)
280
+ return False
281
+
282
+ # Create a new SSH key in 1Password
283
+ self.print_status(f"Creating new SSH key '{ssh_key_title_with_prefix}' in 1Password...", None, 2)
284
+ success, public_key, item_id = create_ssh_key(ssh_key_title_with_prefix, selected_vault)
285
+
286
+ if not success:
287
+ self.print_status("Failed to create SSH key in 1Password", False, 2)
288
+ return False
289
+
290
+ self.print_status("SSH key created successfully in 1Password", True, 2)
291
+
292
+ # Save the public key to the expected location
293
+ if save_public_key(public_key, f"{self.ssh_key_file}.pub"):
294
+ self.print_status(f"Saved public key to {self.ssh_key_file}.pub", True, 2)
295
+ return True
296
+ else:
297
+ self.print_status(f"Failed to save public key to {self.ssh_key_file}.pub", False, 2)
298
+ return False
299
+
275
300
  # Remind user to enable the key in 1Password SSH agent
276
301
  self.print_status("\033[93mImportant: Make sure the key is enabled in 1Password's SSH agent settings\033[0m", None, 2)
277
302
  return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudx-proxy
3
- Version: 0.4.5
3
+ Version: 0.4.6
4
4
  Summary: SSH proxy command to connect VSCode with Cloud9/CloudX instance using AWS Systems Manager
5
5
  Author-email: easytocloud <info@easytocloud.com>
6
6
  License: MIT License
@@ -0,0 +1,12 @@
1
+ cloudx_proxy/_1password.py,sha256=uxyCfVvO1eQrOfYRojst_LN2DV4fIwxM5moaQTn3wQY,5853
2
+ cloudx_proxy/__init__.py,sha256=ZZ2O_m9OFJm18AxMSuYJt4UjSuSqyJlYRaZMoets498,61
3
+ cloudx_proxy/_version.py,sha256=KTwoycq1UXsZO5AtXG8jzeyeaE1ORqxkwO9Pn0qrlwg,511
4
+ cloudx_proxy/cli.py,sha256=VqYdcTn_PC-mhcCpNEa_PcpHjV7vxIDzhfxu-WKlDdU,4904
5
+ cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
6
+ cloudx_proxy/setup.py,sha256=QrInbZdghpAYn064h02KmpA9r-nEbVm-LyTcXLxSmXY,39823
7
+ cloudx_proxy-0.4.6.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
8
+ cloudx_proxy-0.4.6.dist-info/METADATA,sha256=LV5xMR7w2qrmcID563IlI83R7X2SOxzcRo_qKLbBa9k,18522
9
+ cloudx_proxy-0.4.6.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
10
+ cloudx_proxy-0.4.6.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
11
+ cloudx_proxy-0.4.6.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
12
+ cloudx_proxy-0.4.6.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- cloudx_proxy/_1password.py,sha256=uxyCfVvO1eQrOfYRojst_LN2DV4fIwxM5moaQTn3wQY,5853
2
- cloudx_proxy/__init__.py,sha256=ZZ2O_m9OFJm18AxMSuYJt4UjSuSqyJlYRaZMoets498,61
3
- cloudx_proxy/_version.py,sha256=YrJwLVAkXjdo87YWYyrI7_B7BOSjbDIJ_FAFmb7g_vc,511
4
- cloudx_proxy/cli.py,sha256=5IcfYFACUOa4pqSKuHucqZionI9P8n5ZLvtzyXYeTvw,4218
5
- cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
6
- cloudx_proxy/setup.py,sha256=TMFSo3-RusvQ5G7_I0vUPtZG18yDnogQbRDxGxVtNnM,38632
7
- cloudx_proxy-0.4.5.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
8
- cloudx_proxy-0.4.5.dist-info/METADATA,sha256=heC8F4kGgkmgSy-8SdqpgsKsGZ27N3xNkZI8wR3nogw,18522
9
- cloudx_proxy-0.4.5.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
10
- cloudx_proxy-0.4.5.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
11
- cloudx_proxy-0.4.5.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
12
- cloudx_proxy-0.4.5.dist-info/RECORD,,