cloudx-proxy 0.3.14__tar.gz → 0.3.15__tar.gz
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-0.3.14 → cloudx_proxy-0.3.15}/CHANGELOG.md +8 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/PKG-INFO +1 -1
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy/_version.py +2 -2
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy/cli.py +7 -3
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy/core.py +9 -3
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy/setup.py +49 -31
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/PKG-INFO +1 -1
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/.github/workflows/release.yml +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/.gitignore +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/.releaserc +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/CONTRIBUTING.md +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/LICENSE +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/README.md +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy/__init__.py +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/SOURCES.txt +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/dependency_links.txt +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/entry_points.txt +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/requires.txt +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/cloudx_proxy.egg-info/top_level.txt +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/package.json +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/pyproject.toml +0 -0
- {cloudx_proxy-0.3.14 → cloudx_proxy-0.3.15}/setup.cfg +0 -0
@@ -1,3 +1,11 @@
|
|
1
|
+
## [0.3.15](https://github.com/easytocloud/cloudX-proxy/compare/v0.3.14...v0.3.15) (2025-03-06)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* added --ssh-config ([893d919](https://github.com/easytocloud/cloudX-proxy/commit/893d919f7ef30dc5fd41a06b2c032d0035180e80))
|
7
|
+
* added --ssh-config also in connect ([75b7b3b](https://github.com/easytocloud/cloudX-proxy/commit/75b7b3b5ecac5f1a1012ce9d4905bc5aed444915))
|
8
|
+
|
1
9
|
## [0.3.14](https://github.com/easytocloud/cloudX-proxy/compare/v0.3.13...v0.3.14) (2025-03-06)
|
2
10
|
|
3
11
|
|
@@ -17,8 +17,9 @@ def cli():
|
|
17
17
|
@click.option('--profile', default='vscode', help='AWS profile to use (default: vscode)')
|
18
18
|
@click.option('--region', help='AWS region (default: from profile, or eu-west-1 if not set)')
|
19
19
|
@click.option('--ssh-key', default='vscode', help='SSH key name to use (default: vscode)')
|
20
|
+
@click.option('--ssh-config', help='SSH config file to use (default: ~/.ssh/vscode/config)')
|
20
21
|
@click.option('--aws-env', help='AWS environment directory (default: ~/.aws, use name of directory in ~/.aws/aws-envs/)')
|
21
|
-
def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str, aws_env: str):
|
22
|
+
def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str, ssh_config: str, aws_env: str):
|
22
23
|
"""Connect to an EC2 instance via SSM.
|
23
24
|
|
24
25
|
INSTANCE_ID is the EC2 instance ID to connect to (e.g., i-0123456789abcdef0)
|
@@ -35,6 +36,7 @@ def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str
|
|
35
36
|
profile=profile,
|
36
37
|
region=region,
|
37
38
|
ssh_key=ssh_key,
|
39
|
+
ssh_config=ssh_config,
|
38
40
|
aws_env=aws_env
|
39
41
|
)
|
40
42
|
|
@@ -48,8 +50,9 @@ def connect(instance_id: str, port: int, profile: str, region: str, ssh_key: str
|
|
48
50
|
@cli.command()
|
49
51
|
@click.option('--profile', default='vscode', help='AWS profile to use (default: vscode)')
|
50
52
|
@click.option('--ssh-key', default='vscode', help='SSH key name to use (default: vscode)')
|
53
|
+
@click.option('--ssh-config', help='SSH config file to use (default: ~/.ssh/vscode/config)')
|
51
54
|
@click.option('--aws-env', help='AWS environment directory (default: ~/.aws, use name of directory in ~/.aws/aws-envs/)')
|
52
|
-
def setup(profile: str, ssh_key: str, aws_env: str):
|
55
|
+
def setup(profile: str, ssh_key: str, ssh_config: str, aws_env: str):
|
53
56
|
"""Set up AWS profile, SSH keys, and configuration for CloudX.
|
54
57
|
|
55
58
|
This command will:
|
@@ -61,9 +64,10 @@ def setup(profile: str, ssh_key: str, aws_env: str):
|
|
61
64
|
Example usage:
|
62
65
|
cloudx-proxy setup
|
63
66
|
cloudx-proxy setup --profile myprofile --ssh-key mykey
|
67
|
+
cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config
|
64
68
|
"""
|
65
69
|
try:
|
66
|
-
setup = CloudXSetup(profile=profile, ssh_key=ssh_key, aws_env=aws_env)
|
70
|
+
setup = CloudXSetup(profile=profile, ssh_key=ssh_key, ssh_config=ssh_config, aws_env=aws_env)
|
67
71
|
|
68
72
|
print("\n\033[1;95m=== cloudx-proxy Setup ===\033[0m\n")
|
69
73
|
|
@@ -7,7 +7,7 @@ from botocore.exceptions import ClientError
|
|
7
7
|
|
8
8
|
class CloudXProxy:
|
9
9
|
def __init__(self, instance_id: str, port: int = 22, profile: str = "vscode",
|
10
|
-
region: str = None, ssh_key: str = "vscode", aws_env: str = None):
|
10
|
+
region: str = None, ssh_key: str = "vscode", ssh_config: str = None, aws_env: str = None):
|
11
11
|
"""Initialize CloudX client for SSH tunneling via AWS SSM.
|
12
12
|
|
13
13
|
Args:
|
@@ -39,8 +39,14 @@ class CloudXProxy:
|
|
39
39
|
self.ec2 = self.session.client('ec2')
|
40
40
|
self.ec2_connect = self.session.client('ec2-instance-connect')
|
41
41
|
|
42
|
-
# Set up SSH key
|
43
|
-
|
42
|
+
# Set up SSH configuration and key paths
|
43
|
+
if ssh_config:
|
44
|
+
self.ssh_config_file = os.path.expanduser(ssh_config)
|
45
|
+
self.ssh_dir = os.path.dirname(self.ssh_config_file)
|
46
|
+
else:
|
47
|
+
self.ssh_dir = os.path.expanduser("~/.ssh/vscode")
|
48
|
+
self.ssh_config_file = os.path.join(self.ssh_dir, "config")
|
49
|
+
|
44
50
|
self.ssh_key = os.path.join(self.ssh_dir, f"{ssh_key}.pub")
|
45
51
|
|
46
52
|
def log(self, message: str) -> None:
|
@@ -9,20 +9,28 @@ import boto3
|
|
9
9
|
from botocore.exceptions import ClientError
|
10
10
|
|
11
11
|
class CloudXSetup:
|
12
|
-
def __init__(self, profile: str = "vscode", ssh_key: str = "vscode", aws_env: str = None):
|
12
|
+
def __init__(self, profile: str = "vscode", ssh_key: str = "vscode", ssh_config: str = None, aws_env: str = None):
|
13
13
|
"""Initialize cloudx-proxy setup.
|
14
14
|
|
15
15
|
Args:
|
16
16
|
profile: AWS profile name (default: "vscode")
|
17
17
|
ssh_key: SSH key name (default: "vscode")
|
18
|
+
ssh_config: SSH config file path (default: None, uses ~/.ssh/vscode/config)
|
18
19
|
aws_env: AWS environment directory (default: None)
|
19
20
|
"""
|
20
21
|
self.profile = profile
|
21
22
|
self.ssh_key = ssh_key
|
22
23
|
self.aws_env = aws_env
|
23
24
|
self.home_dir = str(Path.home())
|
24
|
-
|
25
|
-
|
25
|
+
|
26
|
+
# Set up ssh config paths based on provided config or default
|
27
|
+
if ssh_config:
|
28
|
+
self.ssh_config_file = Path(os.path.expanduser(ssh_config))
|
29
|
+
self.ssh_dir = self.ssh_config_file.parent
|
30
|
+
else:
|
31
|
+
self.ssh_dir = Path(self.home_dir) / ".ssh" / "vscode"
|
32
|
+
self.ssh_config_file = self.ssh_dir / "config"
|
33
|
+
|
26
34
|
self.ssh_key_file = self.ssh_dir / f"{ssh_key}"
|
27
35
|
self.default_env = None
|
28
36
|
|
@@ -330,8 +338,10 @@ Host cloudx-{cloudx_env}-{hostname}
|
|
330
338
|
if f"Host cloudx-{cloudx_env}-*" in current_config:
|
331
339
|
self.print_status(f"Found existing config for cloudx-{cloudx_env}-*", True, 2)
|
332
340
|
choice = self.prompt(
|
333
|
-
"Would you like to \n
|
334
|
-
"
|
341
|
+
"Would you like to \n"
|
342
|
+
" 1: override the existing config\n"
|
343
|
+
" 2: add settings to the specific host entry?\n"
|
344
|
+
"Select an option",
|
335
345
|
"1"
|
336
346
|
)
|
337
347
|
if choice == "2":
|
@@ -358,6 +368,7 @@ Host cloudx-{cloudx_env}-{hostname}
|
|
358
368
|
# Create base config
|
359
369
|
self.print_status(f"Creating new config for cloudx-{cloudx_env}-*", None, 2)
|
360
370
|
# Build ProxyCommand with only non-default parameters
|
371
|
+
# We don't need to include ssh_config here as SSH will handle that through the config
|
361
372
|
proxy_command = "uvx cloudx-proxy connect %h %p"
|
362
373
|
if self.profile != "vscode":
|
363
374
|
proxy_command += f" --profile {self.profile}"
|
@@ -420,7 +431,9 @@ Host cloudx-{cloudx_env}-{hostname}
|
|
420
431
|
f.write(host_entry)
|
421
432
|
self.print_status("Host entry added", True, 2)
|
422
433
|
|
423
|
-
#
|
434
|
+
# Handle system SSH config integration
|
435
|
+
system_config_path = Path(self.home_dir) / ".ssh" / "config"
|
436
|
+
|
424
437
|
# Ensure ~/.ssh directory has proper permissions
|
425
438
|
ssh_parent_dir = Path(self.home_dir) / ".ssh"
|
426
439
|
if not ssh_parent_dir.exists():
|
@@ -428,36 +441,41 @@ Host cloudx-{cloudx_env}-{hostname}
|
|
428
441
|
self.print_status(f"Created SSH directory: {ssh_parent_dir}", True, 2)
|
429
442
|
self._set_directory_permissions(ssh_parent_dir)
|
430
443
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
if main_config.exists():
|
435
|
-
content = main_config.read_text()
|
436
|
-
if include_line not in content:
|
437
|
-
with open(main_config, 'a') as f:
|
438
|
-
f.write(f"\n{include_line}")
|
439
|
-
self.print_status("Added include line to main SSH config", True, 2)
|
440
|
-
else:
|
441
|
-
self.print_status("Main SSH config already includes our config", True, 2)
|
442
|
-
|
443
|
-
# Set correct permissions on main config file
|
444
|
-
if platform.system() != 'Windows':
|
445
|
-
import stat
|
446
|
-
main_config.chmod(stat.S_IRUSR | stat.S_IWUSR) # 600 permissions
|
447
|
-
self.print_status("Set main config file permissions to 600", True, 2)
|
444
|
+
# If our config file is the system config, we're done
|
445
|
+
if self.ssh_config_file.samefile(system_config_path) if self.ssh_config_file.exists() and system_config_path.exists() else str(self.ssh_config_file) == str(system_config_path):
|
446
|
+
self.print_status("Using system SSH config directly, no Include needed", True, 2)
|
448
447
|
else:
|
449
|
-
|
450
|
-
|
448
|
+
# Otherwise, make sure the system config includes our config file
|
449
|
+
include_line = f"Include {self.ssh_config_file}\n"
|
451
450
|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
451
|
+
if system_config_path.exists():
|
452
|
+
content = system_config_path.read_text()
|
453
|
+
if include_line not in content:
|
454
|
+
with open(system_config_path, 'a') as f:
|
455
|
+
f.write(f"\n{include_line}")
|
456
|
+
self.print_status("Added include line to system SSH config", True, 2)
|
457
|
+
else:
|
458
|
+
self.print_status("System SSH config already includes our config", True, 2)
|
459
|
+
|
460
|
+
# Set correct permissions on system config file
|
461
|
+
if platform.system() != 'Windows':
|
462
|
+
import stat
|
463
|
+
system_config_path.chmod(stat.S_IRUSR | stat.S_IWUSR) # 600 permissions
|
464
|
+
self.print_status("Set system config file permissions to 600", True, 2)
|
465
|
+
else:
|
466
|
+
system_config_path.write_text(include_line)
|
467
|
+
self.print_status("Created system SSH config with include line", True, 2)
|
468
|
+
|
469
|
+
# Set correct permissions on newly created system config file
|
470
|
+
if platform.system() != 'Windows':
|
471
|
+
import stat
|
472
|
+
system_config_path.chmod(stat.S_IRUSR | stat.S_IWUSR) # 600 permissions
|
473
|
+
self.print_status("Set system config file permissions to 600", True, 2)
|
457
474
|
|
458
475
|
self.print_status("SSH configuration summary:", None)
|
459
|
-
self.print_status(f"
|
476
|
+
self.print_status(f"System config: {system_config_path}", None, 2)
|
460
477
|
self.print_status(f"cloudx-proxy config: {self.ssh_config_file}", None, 2)
|
478
|
+
self.print_status(f"SSH key directory: {self.ssh_dir}", None, 2)
|
461
479
|
self.print_status(f"Connect using: ssh cloudx-{cloudx_env}-{hostname}", None, 2)
|
462
480
|
|
463
481
|
return True
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|