cloudx-proxy 0.4.10__py3-none-any.whl → 0.4.11__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 +2 -2
- cloudx_proxy/cli.py +22 -6
- cloudx_proxy/setup.py +68 -19
- {cloudx_proxy-0.4.10.dist-info → cloudx_proxy-0.4.11.dist-info}/METADATA +8 -3
- cloudx_proxy-0.4.11.dist-info/RECORD +12 -0
- cloudx_proxy-0.4.10.dist-info/RECORD +0 -12
- {cloudx_proxy-0.4.10.dist-info → cloudx_proxy-0.4.11.dist-info}/LICENSE +0 -0
- {cloudx_proxy-0.4.10.dist-info → cloudx_proxy-0.4.11.dist-info}/WHEEL +0 -0
- {cloudx_proxy-0.4.10.dist-info → cloudx_proxy-0.4.11.dist-info}/entry_points.txt +0 -0
- {cloudx_proxy-0.4.10.dist-info → cloudx_proxy-0.4.11.dist-info}/top_level.txt +0 -0
cloudx_proxy/_version.py
CHANGED
cloudx_proxy/cli.py
CHANGED
@@ -10,7 +10,17 @@ from .setup import CloudXSetup
|
|
10
10
|
@click.group()
|
11
11
|
@click.version_option(version=__version__)
|
12
12
|
def cli():
|
13
|
-
"""cloudx-proxy - SSH proxy to connect VSCode Remote SSH to EC2 instances using SSM.
|
13
|
+
"""cloudx-proxy - SSH proxy to connect VSCode Remote SSH to EC2 instances using SSM.
|
14
|
+
|
15
|
+
This tool enables seamless SSH connections from VSCode to EC2 instances using AWS Systems Manager,
|
16
|
+
eliminating the need for direct SSH access or public IP addresses.
|
17
|
+
|
18
|
+
Main commands:
|
19
|
+
|
20
|
+
setup - Configure AWS profile, SSH keys, and SSH configuration
|
21
|
+
connect - Connect to an EC2 instance via SSM
|
22
|
+
list - List configured SSH hosts
|
23
|
+
"""
|
14
24
|
pass
|
15
25
|
|
16
26
|
@cli.command()
|
@@ -27,9 +37,11 @@ def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str
|
|
27
37
|
INSTANCE_ID is the EC2 instance ID to connect to (e.g., i-0123456789abcdef0)
|
28
38
|
|
29
39
|
Example usage:
|
30
|
-
|
31
|
-
cloudx-proxy i-0123456789abcdef0 22
|
32
|
-
cloudx-proxy i-0123456789abcdef0 22 --
|
40
|
+
|
41
|
+
cloudx-proxy connect i-0123456789abcdef0 22
|
42
|
+
cloudx-proxy connect i-0123456789abcdef0 22 --profile myprofile --region eu-west-1
|
43
|
+
cloudx-proxy connect i-0123456789abcdef0 22 --ssh-config ~/.ssh/cloudx/config
|
44
|
+
cloudx-proxy connect i-0123456789abcdef0 22 --aws-env prod
|
33
45
|
"""
|
34
46
|
try:
|
35
47
|
client = CloudXProxy(
|
@@ -56,25 +68,28 @@ def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str
|
|
56
68
|
@click.option('--ssh-key', default='vscode', help='SSH key name to use (default: vscode)')
|
57
69
|
@click.option('--ssh-config', help='SSH config file to use (default: ~/.ssh/vscode/config)')
|
58
70
|
@click.option('--aws-env', help='AWS environment directory (default: ~/.aws, use name of directory in ~/.aws/aws-envs/)')
|
59
|
-
@click.option('--1password', 'use_1password',
|
71
|
+
@click.option('--1password', 'use_1password', default=None, help='Use 1Password SSH agent for SSH authentication. Optionally specify vault name (default: "Private")')
|
60
72
|
@click.option('--instance', help='EC2 instance ID to set up connection for')
|
61
73
|
@click.option('--hostname', help='Hostname to use for SSH configuration')
|
62
74
|
@click.option('--yes', 'non_interactive', is_flag=True, help='Non-interactive mode, use default values for all prompts')
|
63
|
-
def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1password:
|
75
|
+
def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str, use_1password: str,
|
64
76
|
instance: str, hostname: str, non_interactive: bool):
|
65
77
|
"""Set up AWS profile, SSH keys, and configuration for CloudX.
|
66
78
|
|
67
79
|
This command will:
|
80
|
+
|
68
81
|
1. Set up AWS profile with credentials
|
69
82
|
2. Create or use existing SSH key
|
70
83
|
3. Configure SSH for CloudX instances
|
71
84
|
4. Check instance setup status
|
72
85
|
|
73
86
|
Example usage:
|
87
|
+
|
74
88
|
cloudx-proxy setup
|
75
89
|
cloudx-proxy setup --profile myprofile --ssh-key mykey
|
76
90
|
cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config
|
77
91
|
cloudx-proxy setup --1password
|
92
|
+
cloudx-proxy setup --1password Work
|
78
93
|
cloudx-proxy setup --instance i-0123456789abcdef0 --hostname myserver --yes
|
79
94
|
"""
|
80
95
|
try:
|
@@ -136,6 +151,7 @@ def list(ssh_config: str, environment: str, detailed: bool):
|
|
136
151
|
Hosts are grouped by environment for easier navigation.
|
137
152
|
|
138
153
|
Example usage:
|
154
|
+
|
139
155
|
cloudx-proxy list
|
140
156
|
cloudx-proxy list --environment dev
|
141
157
|
cloudx-proxy list --ssh-config ~/.ssh/cloudx/config
|
cloudx_proxy/setup.py
CHANGED
@@ -14,7 +14,7 @@ class CloudXSetup:
|
|
14
14
|
SSH_KEY_PREFIX = "cloudX SSH Key - "
|
15
15
|
|
16
16
|
def __init__(self, profile: str = "vscode", ssh_key: str = "vscode", ssh_config: str = None,
|
17
|
-
aws_env: str = None, use_1password:
|
17
|
+
aws_env: str = None, use_1password: str = None, instance_id: str = None,
|
18
18
|
non_interactive: bool = False):
|
19
19
|
"""Initialize cloudx-proxy setup.
|
20
20
|
|
@@ -23,14 +23,24 @@ class CloudXSetup:
|
|
23
23
|
ssh_key: SSH key name (default: "vscode")
|
24
24
|
ssh_config: SSH config file path (default: None, uses ~/.ssh/vscode/config)
|
25
25
|
aws_env: AWS environment directory (default: None)
|
26
|
-
use_1password: Use 1Password SSH agent for authentication (default:
|
26
|
+
use_1password: Use 1Password SSH agent for authentication. Can be True/False or a vault name (default: None)
|
27
27
|
instance_id: EC2 instance ID to set up connection for (optional)
|
28
28
|
non_interactive: Non-interactive mode, use defaults for all prompts (default: False)
|
29
29
|
"""
|
30
30
|
self.profile = profile
|
31
31
|
self.ssh_key = ssh_key
|
32
32
|
self.aws_env = aws_env
|
33
|
-
|
33
|
+
|
34
|
+
# Handle 1Password integration
|
35
|
+
if use_1password is None:
|
36
|
+
self.use_1password = False
|
37
|
+
self.op_vault = None
|
38
|
+
elif isinstance(use_1password, bool) or use_1password.lower() == 'true':
|
39
|
+
self.use_1password = True
|
40
|
+
self.op_vault = "Private" # Default vault
|
41
|
+
else:
|
42
|
+
self.use_1password = True
|
43
|
+
self.op_vault = use_1password
|
34
44
|
self.instance_id = instance_id
|
35
45
|
self.non_interactive = non_interactive
|
36
46
|
self.home_dir = str(Path.home())
|
@@ -209,6 +219,13 @@ class CloudXSetup:
|
|
209
219
|
return False
|
210
220
|
|
211
221
|
self.print_status("1Password SSH agent is running", True, 2)
|
222
|
+
|
223
|
+
# If using a vault other than "Private", warn the user
|
224
|
+
if self.op_vault and self.op_vault != "Private":
|
225
|
+
self.print_status(f"\033[93mWarning: Using vault '{self.op_vault}' instead of default 'Private' vault\033[0m", None, 2)
|
226
|
+
self.print_status("\033[93mMake sure to enable this vault for SSH in 1Password settings\033[0m", None, 2)
|
227
|
+
self.print_status("\033[93mBy default, only the 'Private' vault is enabled for SSH\033[0m", None, 2)
|
228
|
+
|
212
229
|
return True
|
213
230
|
|
214
231
|
def _create_1password_key(self) -> bool:
|
@@ -261,23 +278,55 @@ class CloudXSetup:
|
|
261
278
|
self.print_status("No 1Password vaults found", False, 2)
|
262
279
|
return False
|
263
280
|
|
264
|
-
#
|
265
|
-
self.
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
281
|
+
# Use the specified vault or prompt the user to select one
|
282
|
+
if self.op_vault:
|
283
|
+
# Find the vault by name
|
284
|
+
selected_vault = None
|
285
|
+
for vault in vaults:
|
286
|
+
if vault['name'].lower() == self.op_vault.lower():
|
287
|
+
selected_vault = vault['id']
|
288
|
+
self.print_status(f"Using specified 1Password vault: {self.op_vault}", True, 2)
|
289
|
+
break
|
290
|
+
|
291
|
+
# If the specified vault wasn't found, warn the user and prompt for selection
|
292
|
+
if not selected_vault:
|
293
|
+
self.print_status(f"Specified vault '{self.op_vault}' not found", False, 2)
|
294
|
+
|
295
|
+
# Display available vaults
|
296
|
+
self.print_status("Available 1Password vaults:", None, 2)
|
297
|
+
print("\n\033[96mAvailable 1Password vaults:\033[0m")
|
298
|
+
for i, vault in enumerate(vaults):
|
299
|
+
print(f" {i+1}. {vault['name']}")
|
300
|
+
|
301
|
+
# Let user select vault
|
302
|
+
vault_num = self.prompt("Select vault number to store SSH key", "1")
|
303
|
+
try:
|
304
|
+
vault_idx = int(vault_num) - 1
|
305
|
+
if vault_idx < 0 or vault_idx >= len(vaults):
|
306
|
+
self.print_status("Invalid vault number", False, 2)
|
307
|
+
return False
|
308
|
+
selected_vault = vaults[vault_idx]['id']
|
309
|
+
except ValueError:
|
310
|
+
self.print_status("Invalid input", False, 2)
|
311
|
+
return False
|
312
|
+
else:
|
313
|
+
# No vault specified, prompt the user
|
314
|
+
self.print_status("Creating a new SSH key in 1Password", None, 2)
|
315
|
+
print("\n\033[96mAvailable 1Password vaults:\033[0m")
|
316
|
+
for i, vault in enumerate(vaults):
|
317
|
+
print(f" {i+1}. {vault['name']}")
|
318
|
+
|
319
|
+
# Let user select vault
|
320
|
+
vault_num = self.prompt("Select vault number to store SSH key", "1")
|
321
|
+
try:
|
322
|
+
vault_idx = int(vault_num) - 1
|
323
|
+
if vault_idx < 0 or vault_idx >= len(vaults):
|
324
|
+
self.print_status("Invalid vault number", False, 2)
|
325
|
+
return False
|
326
|
+
selected_vault = vaults[vault_idx]['id']
|
327
|
+
except ValueError:
|
328
|
+
self.print_status("Invalid input", False, 2)
|
276
329
|
return False
|
277
|
-
selected_vault = vaults[vault_idx]['id']
|
278
|
-
except ValueError:
|
279
|
-
self.print_status("Invalid input", False, 2)
|
280
|
-
return False
|
281
330
|
|
282
331
|
# Create a new SSH key in 1Password
|
283
332
|
self.print_status(f"Creating new SSH key '{ssh_key_title_with_prefix}' in 1Password...", None, 2)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: cloudx-proxy
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.11
|
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
|
@@ -275,7 +275,7 @@ Options:
|
|
275
275
|
- `--profile` (default: vscode): AWS profile to use. The profile's IAM user should follow the format cloudX-{env}-{user}. The environment part will be used as the default environment during setup.
|
276
276
|
- `--ssh-key` (default: vscode): Name of the SSH key to create/use. The key will be stored in the SSH config directory. This same name can be used in the connect command.
|
277
277
|
- `--ssh-config` (optional): Path to the SSH config file to use. If specified, configuration and keys will be stored in this location. Default is ~/.ssh/vscode/config.
|
278
|
-
- `--1password` (
|
278
|
+
- `--1password` (optional): Enable 1Password SSH agent integration. Can be used as a flag or with a vault name (e.g., `--1password Private`). Creates keys directly in 1Password and configures SSH to use the 1Password SSH agent. If a vault name is specified, that vault will be used for key storage. By default, the "Private" vault is used. Note that only the "Private" vault is enabled for SSH by default in 1Password settings.
|
279
279
|
- `--aws-env` (optional): AWS environment directory to use. If specified, AWS configuration and credentials will be read from ~/.aws/aws-envs/{env}/.
|
280
280
|
- `--instance` (optional): EC2 instance ID to set up connection for. If provided, skips the instance ID prompt.
|
281
281
|
- `--hostname` (optional): Hostname to use for SSH configuration. If not provided, a hostname will be generated from the instance ID in non-interactive mode or prompted for in interactive mode.
|
@@ -289,9 +289,12 @@ uvx cloudx-proxy setup
|
|
289
289
|
# Setup with custom profile and key
|
290
290
|
uvx cloudx-proxy setup --profile myprofile --ssh-key mykey
|
291
291
|
|
292
|
-
# Setup with custom SSH config and 1Password integration
|
292
|
+
# Setup with custom SSH config and 1Password integration (uses default "Private" vault)
|
293
293
|
uvx cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config --1password
|
294
294
|
|
295
|
+
# Setup with 1Password integration using a specific vault
|
296
|
+
uvx cloudx-proxy setup --1password Work
|
297
|
+
|
295
298
|
# Complete setup with all options
|
296
299
|
uvx cloudx-proxy setup --profile myprofile --ssh-key mykey --ssh-config ~/.ssh/cloudx/config --1password --aws-env prod
|
297
300
|
```
|
@@ -412,6 +415,8 @@ These permissions are required to bootstrap the instance, so that after creation
|
|
412
415
|
* SSH agent is enabled in 1Password settings
|
413
416
|
* Keys are added to the SSH agent in 1Password
|
414
417
|
* The key is visible with `op item list --categories "SSH Key"`
|
418
|
+
* If using a vault other than "Private", ensure that vault is enabled for SSH in 1Password settings
|
419
|
+
* By default, only the "Private" vault is enabled for SSH in 1Password
|
415
420
|
|
416
421
|
4. **AWS Configuration**
|
417
422
|
- Confirm AWS CLI is configured with valid credentials
|
@@ -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=lmDCfh4BJbHyJNIpLPplzDhSqyNzLbtZmdO47e5QgpA,513
|
4
|
+
cloudx_proxy/cli.py,sha256=rGr_lefPDZS0s-_qSHuzyZK739z38I9f8qF8cxrOsDg,9969
|
5
|
+
cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
|
6
|
+
cloudx_proxy/setup.py,sha256=CmUYr9EhtLoEpKU9jMEgxXtVMYlZTfPAJ-eQ59nr_bI,42785
|
7
|
+
cloudx_proxy-0.4.11.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
8
|
+
cloudx_proxy-0.4.11.dist-info/METADATA,sha256=2vk4-VnmAK49YS8yoMdAtU0miNrmX8P5W_zkHWGVVHY,20585
|
9
|
+
cloudx_proxy-0.4.11.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
10
|
+
cloudx_proxy-0.4.11.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
11
|
+
cloudx_proxy-0.4.11.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
12
|
+
cloudx_proxy-0.4.11.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=65ElcWoBtvl8MKrI33OOSijIy6-SUp9XMvxFyE69sWU,513
|
4
|
-
cloudx_proxy/cli.py,sha256=COcaXVgdIKtnKFmXYaxVVtNbxTmuBNcVJeUD-dv5qUo,9355
|
5
|
-
cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
|
6
|
-
cloudx_proxy/setup.py,sha256=IHjMjUV7INFFvUuaOvQvX7dPbpsa3qiCZriOfWJACKY,40086
|
7
|
-
cloudx_proxy-0.4.10.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
8
|
-
cloudx_proxy-0.4.10.dist-info/METADATA,sha256=sTday7zCaUurBFJuz7M0rHgh1NJIFAXOh-58gN5wssQ,19996
|
9
|
-
cloudx_proxy-0.4.10.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
10
|
-
cloudx_proxy-0.4.10.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
11
|
-
cloudx_proxy-0.4.10.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
12
|
-
cloudx_proxy-0.4.10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|