cloudx-proxy 2025.3.0__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.
@@ -0,0 +1,6 @@
1
+ """CloudX Client - Connect to EC2 instances via SSM for VSCode Remote SSH."""
2
+
3
+ from .core import CloudXClient
4
+ from ._version import __version__
5
+
6
+ __all__ = ["CloudXClient", "__version__"]
@@ -0,0 +1,16 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ TYPE_CHECKING = False
4
+ if TYPE_CHECKING:
5
+ from typing import Tuple, Union
6
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
7
+ else:
8
+ VERSION_TUPLE = object
9
+
10
+ version: str
11
+ __version__: str
12
+ __version_tuple__: VERSION_TUPLE
13
+ version_tuple: VERSION_TUPLE
14
+
15
+ __version__ = version = '2025.3.0'
16
+ __version_tuple__ = version_tuple = (2025, 3, 0)
cloudx_proxy/cli.py ADDED
@@ -0,0 +1,41 @@
1
+ import os
2
+ import sys
3
+ import click
4
+ from .core import CloudXClient
5
+
6
+ @click.command()
7
+ @click.argument('instance_id')
8
+ @click.argument('port', type=int, default=22)
9
+ @click.option('--profile', default='vscode', help='AWS profile to use (default: vscode)')
10
+ @click.option('--region', help='AWS region (default: from profile, or eu-west-1 if not set)')
11
+ @click.option('--key-path', help='Path to SSH public key (default: ~/.ssh/vscode/vscode.pub)')
12
+ @click.option('--aws-env', help='AWS environment directory (default: ~/.aws, use name of directory in ~/.aws/aws-envs/)')
13
+ def main(instance_id: str, port: int, profile: str, region: str, key_path: str, aws_env: str):
14
+ """CloudX Client - Connect to EC2 instances via SSM for VSCode Remote SSH.
15
+
16
+ INSTANCE_ID is the EC2 instance ID to connect to (e.g., i-0123456789abcdef0)
17
+
18
+ Example usage:
19
+ uvx cloudx-client i-0123456789abcdef0 22
20
+ uvx cloudx-client i-0123456789abcdef0 22 --profile myprofile --region eu-west-1
21
+ uvx cloudx-client i-0123456789abcdef0 22 --aws-env prod
22
+ """
23
+ try:
24
+ client = CloudXClient(
25
+ instance_id=instance_id,
26
+ port=port,
27
+ profile=profile,
28
+ region=region,
29
+ public_key_path=key_path,
30
+ aws_env=aws_env
31
+ )
32
+
33
+ if not client.connect():
34
+ sys.exit(1)
35
+
36
+ except Exception as e:
37
+ print(f"Error: {str(e)}", file=sys.stderr)
38
+ sys.exit(1)
39
+
40
+ if __name__ == '__main__':
41
+ main()
cloudx_proxy/core.py ADDED
@@ -0,0 +1,189 @@
1
+ import os
2
+ import sys
3
+ import time
4
+ from pathlib import Path
5
+ import boto3
6
+ from botocore.exceptions import ClientError
7
+
8
+ class CloudXClient:
9
+ def __init__(self, instance_id: str, port: int = 22, profile: str = "vscode",
10
+ region: str = None, public_key_path: str = None, aws_env: str = None):
11
+ """Initialize CloudX client for SSH tunneling via AWS SSM.
12
+
13
+ Args:
14
+ instance_id: EC2 instance ID to connect to
15
+ port: SSH port number (default: 22)
16
+ profile: AWS profile to use (default: "vscode")
17
+ region: AWS region (default: from profile)
18
+ public_key_path: Path to SSH public key (default: ~/.ssh/vscode/vscode.pub)
19
+ aws_env: AWS environment directory (default: None, uses ~/.aws)
20
+ """
21
+ self.instance_id = instance_id
22
+ self.port = port
23
+ self.profile = profile
24
+
25
+ # Configure AWS environment
26
+ if aws_env:
27
+ aws_env_dir = os.path.expanduser(f"~/.aws/aws-envs/{aws_env}")
28
+ os.environ["AWS_CONFIG_FILE"] = os.path.join(aws_env_dir, "config")
29
+ os.environ["AWS_SHARED_CREDENTIALS_FILE"] = os.path.join(aws_env_dir, "credentials")
30
+
31
+ # Set up AWS session with eu-west-1 as default region
32
+ if not region:
33
+ # Try to get region from profile first
34
+ session = boto3.Session(profile_name=profile)
35
+ region = session.region_name or 'eu-west-1'
36
+
37
+ self.session = boto3.Session(profile_name=profile, region_name=region)
38
+ self.ssm = self.session.client('ssm')
39
+ self.ec2 = self.session.client('ec2')
40
+ self.ec2_connect = self.session.client('ec2-instance-connect')
41
+
42
+ # Default public key path if not provided
43
+ if not public_key_path:
44
+ public_key_path = os.path.expanduser("~/.ssh/vscode/vscode.pub")
45
+ self.public_key_path = Path(public_key_path)
46
+
47
+ def log(self, message: str) -> None:
48
+ """Log message to stderr to avoid interfering with SSH connection."""
49
+ print(message, file=sys.stderr)
50
+
51
+ def get_instance_status(self) -> str:
52
+ """Check if instance is online in SSM."""
53
+ try:
54
+ response = self.ssm.describe_instance_information(
55
+ Filters=[{'Key': 'InstanceIds', 'Values': [self.instance_id]}]
56
+ )
57
+ if response['InstanceInformationList']:
58
+ return response['InstanceInformationList'][0]['PingStatus']
59
+ return 'Offline'
60
+ except ClientError:
61
+ return 'Offline'
62
+
63
+ def start_instance(self) -> bool:
64
+ """Start the EC2 instance if it's stopped."""
65
+ try:
66
+ self.ec2.start_instances(InstanceIds=[self.instance_id])
67
+ return True
68
+ except ClientError as e:
69
+ self.log(f"Error starting instance: {e}")
70
+ return False
71
+
72
+ def wait_for_instance(self, max_attempts: int = 30, delay: int = 3) -> bool:
73
+ """Wait for instance to come online.
74
+
75
+ Args:
76
+ max_attempts: Maximum number of status checks
77
+ delay: Seconds between checks
78
+
79
+ Returns:
80
+ bool: True if instance came online, False if timeout
81
+ """
82
+ for _ in range(max_attempts):
83
+ if self.get_instance_status() == 'Online':
84
+ return True
85
+ time.sleep(delay)
86
+ return False
87
+
88
+ def push_ssh_key(self) -> bool:
89
+ """Push SSH public key to instance via EC2 Instance Connect."""
90
+ try:
91
+ with open(self.public_key_path) as f:
92
+ public_key = f.read()
93
+
94
+ self.ec2_connect.send_ssh_public_key(
95
+ InstanceId=self.instance_id,
96
+ InstanceOSUser='ec2-user',
97
+ SSHPublicKey=public_key
98
+ )
99
+ return True
100
+ except (ClientError, FileNotFoundError) as e:
101
+ self.log(f"Error pushing SSH key: {e}")
102
+ return False
103
+
104
+ def start_session(self) -> None:
105
+ """Start SSM session with SSH port forwarding.
106
+
107
+ Uses AWS CLI directly to ensure proper stdin/stdout handling for SSH ProxyCommand.
108
+ The session manager plugin will automatically handle the data transfer.
109
+
110
+ When used as a ProxyCommand, we need to:
111
+ 1. Pass through stdin/stdout directly to AWS CLI
112
+ 2. Only use stderr for logging
113
+ 3. Let the session manager plugin handle the actual data transfer
114
+ """
115
+ import subprocess
116
+ import platform
117
+
118
+ try:
119
+ # Build environment with AWS credentials configuration
120
+ env = os.environ.copy()
121
+ if 'AWS_CONFIG_FILE' in os.environ:
122
+ env['AWS_CONFIG_FILE'] = os.environ['AWS_CONFIG_FILE']
123
+ if 'AWS_SHARED_CREDENTIALS_FILE' in os.environ:
124
+ env['AWS_SHARED_CREDENTIALS_FILE'] = os.environ['AWS_SHARED_CREDENTIALS_FILE']
125
+
126
+ # Determine AWS CLI command based on platform
127
+ aws_cmd = 'aws.exe' if platform.system() == 'Windows' else 'aws'
128
+
129
+ # Build command as list (works for both Windows and Unix)
130
+ cmd = [
131
+ aws_cmd, 'ssm', 'start-session',
132
+ '--target', self.instance_id,
133
+ '--document-name', 'AWS-StartSSHSession',
134
+ '--parameters', f'portNumber={self.port}',
135
+ '--profile', self.profile,
136
+ '--region', self.session.region_name
137
+ ]
138
+
139
+ # Start AWS CLI process with direct stdin/stdout pass-through
140
+ process = subprocess.Popen(
141
+ cmd,
142
+ env=env,
143
+ stdin=sys.stdin,
144
+ stdout=sys.stdout,
145
+ stderr=subprocess.PIPE, # Capture stderr for our logging
146
+ shell=platform.system() == 'Windows' # shell=True only on Windows
147
+ )
148
+
149
+ # Monitor stderr for logging while process runs
150
+ while True:
151
+ err_line = process.stderr.readline()
152
+ if not err_line and process.poll() is not None:
153
+ break
154
+ if err_line:
155
+ self.log(err_line.decode().strip())
156
+
157
+ if process.returncode != 0:
158
+ raise subprocess.CalledProcessError(process.returncode, cmd)
159
+
160
+ except subprocess.CalledProcessError as e:
161
+ self.log(f"Error starting session: {e}")
162
+ raise
163
+
164
+ def connect(self) -> bool:
165
+ """Main connection flow:
166
+ 1. Check instance status
167
+ 2. Start if needed and wait for online
168
+ 3. Push SSH key
169
+ 4. Start SSM session
170
+ """
171
+ status = self.get_instance_status()
172
+
173
+ if status != 'Online':
174
+ self.log(f"Instance {self.instance_id} is {status}, starting...")
175
+ if not self.start_instance():
176
+ return False
177
+
178
+ self.log("Waiting for instance to come online...")
179
+ if not self.wait_for_instance():
180
+ self.log("Instance failed to come online")
181
+ return False
182
+
183
+ self.log("Pushing SSH public key...")
184
+ if not self.push_ssh_key():
185
+ return False
186
+
187
+ self.log("Starting SSM session...")
188
+ self.start_session()
189
+ return True
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 easytocloud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,258 @@
1
+ Metadata-Version: 2.2
2
+ Name: cloudx-proxy
3
+ Version: 2025.3.0
4
+ Summary: SSH proxy command to connect VSCode with Cloud9/CloudX instance using AWS Systems Manager
5
+ Author-email: easytocloud <info@easytocloud.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 easytocloud
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/easytocloud/cloudX-proxy
29
+ Project-URL: Repository, https://github.com/easytocloud/cloudX-proxy.git
30
+ Project-URL: Issues, https://github.com/easytocloud/cloudX-proxy/issues
31
+ Project-URL: Changelog, https://github.com/easytocloud/cloudX-proxy/blob/main/CHANGELOG.md
32
+ Keywords: aws,vscode,cloud9,cloudX,ssm,ssh,proxy
33
+ Classifier: Development Status :: 5 - Production/Stable
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.8
40
+ Classifier: Programming Language :: Python :: 3.9
41
+ Classifier: Programming Language :: Python :: 3.10
42
+ Classifier: Programming Language :: Python :: 3.11
43
+ Classifier: Topic :: Software Development :: Build Tools
44
+ Classifier: Topic :: System :: Systems Administration
45
+ Requires-Python: >=3.8
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE
48
+ Requires-Dist: boto3>=1.34.0
49
+ Requires-Dist: click>=8.1.0
50
+
51
+ # cloudX-proxy
52
+
53
+ A cross-platform SSH proxy command for connecting VSCode to CloudX/Cloud9 EC2 instances using AWS Systems Manager Session Manager.
54
+
55
+ ## Overview
56
+
57
+ cloudX-proxy enables seamless SSH connections from VSCode to EC2 instances using AWS Systems Manager Session Manager, eliminating the need for direct SSH access or public IP addresses. It handles:
58
+
59
+ - Automatic instance startup if stopped
60
+ - SSH key distribution via EC2 Instance Connect
61
+ - SSH tunneling through AWS Systems Manager
62
+ - Cross-platform support (Windows, macOS, Linux)
63
+
64
+ ## Prerequisites
65
+
66
+ 1. **AWS CLI v2** - [Installation Guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
67
+ 2. **AWS Session Manager Plugin** - [Installation Guide](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)
68
+ 3. **OpenSSH Client**
69
+ - Windows: [Microsoft's OpenSSH Installation Guide](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui)
70
+ - macOS/Linux: Usually pre-installed
71
+ 4. **uv** - Python package installer and resolver
72
+ ```bash
73
+ pip install uv
74
+ ```
75
+ 5. **VSCode with Remote SSH Extension** installed
76
+
77
+ ## AWS Credentials Setup
78
+
79
+ The proxy expects to find AWS credentials in a profile named 'vscode' by default. These credentials should be the Access Key and Secret Key that were created by deploying the cloudX-user stack in your AWS account. The cloudX-user stack creates an IAM user with the minimal permissions required for:
80
+ - Starting/stopping EC2 instances
81
+ - Establishing SSM sessions
82
+ - Pushing SSH keys via EC2 Instance Connect
83
+
84
+ Once the SSH session is established, the user has to further configure the instance using `generate-sso-config` tool. This is a one-time setup unless the user's access to AWS accounts changes, in which case the user should re-run the `generate-sso-config` tool.
85
+
86
+ It is recommended to use --generate-directories and --use-ou-structure to create working directories for each account the user has access to.
87
+
88
+ Everytime the user connects to the instance, `ssostart` will authenticate the user with AWS SSO and generate temporary credentials.
89
+
90
+ This ensures you have the appropriate AWS access both for connecting to the instance and for working within it.
91
+
92
+ The proxy also supports easytocloud's AWS profile organizer. If you use multiple AWS environments, you can store your AWS configuration and credentials in `~/.aws/aws-envs/<environment>` directories and use the `--aws-env` option to specify which environment to use.
93
+
94
+ ## Setup
95
+
96
+ 1. Deploy the cloudX-user stack in your AWS account to create the necessary IAM user
97
+ 2. Configure the 'vscode' AWS profile with the credentials from the cloudX-user stack
98
+ 3. Install uv if you haven't already:
99
+ ```bash
100
+ pip install uv
101
+ ```
102
+
103
+ The `uvx` command, part of the uv package manager, makes running cloudX-proxy seamless. When you run `uvx cloudx-proxy`, it automatically:
104
+ - Pulls the latest version from PyPI
105
+ - Creates an isolated virtual environment
106
+ - Installs all dependencies
107
+ - Runs the code
108
+
109
+ All of this happens in a single, fast operation without any manual setup required.
110
+
111
+ ## SSH Configuration
112
+
113
+ ### 1. Generate SSH Key Pair
114
+
115
+ If you don't already have an SSH key pair for VSCode:
116
+
117
+ ```bash
118
+ # Create .ssh/vscode directory
119
+ mkdir -p ~/.ssh/vscode
120
+
121
+ # Generate key pair
122
+ ssh-keygen -t rsa -b 4096 -f ~/.ssh/vscode/vscode
123
+ ```
124
+
125
+ ### 2. Configure SSH
126
+
127
+ #### Unix-like Systems (macOS/Linux)
128
+
129
+ 1. Create or edit `~/.ssh/config`:
130
+ ```bash
131
+ # Include VSCode-specific config
132
+ Include vscode/config
133
+ ```
134
+
135
+ 2. Create `~/.ssh/vscode/config`:
136
+ ```
137
+ Host cloudx-*
138
+ ProxyCommand uvx cloudx-proxy %h %p
139
+ User ec2-user
140
+ IdentityFile ~/.ssh/vscode/vscode
141
+ StrictHostKeyChecking no
142
+ UserKnownHostsFile /dev/null
143
+
144
+ # Example host configuration
145
+ Host cloudx-dev
146
+ HostName i-0123456789abcdef0 # Your EC2 instance ID
147
+ ```
148
+
149
+ #### Windows
150
+
151
+ 1. Create or edit `%USERPROFILE%\.ssh\config`:
152
+ ```
153
+ Include vscode/config
154
+ ```
155
+
156
+ 2. Create `%USERPROFILE%\.ssh\vscode\config`:
157
+ ```
158
+ Host cloudx-*
159
+ ProxyCommand uvx cloudx-proxy %h %p
160
+ User ec2-user
161
+ IdentityFile %USERPROFILE%\.ssh\vscode\vscode
162
+ StrictHostKeyChecking no
163
+ UserKnownHostsFile /dev/null
164
+
165
+ # Example host configuration
166
+ Host cloudx-dev
167
+ HostName i-0123456789abcdef0 # Your EC2 instance ID
168
+ ```
169
+
170
+ ### 3. VSCode Configuration
171
+
172
+ 1. Install the "Remote - SSH" extension in VSCode
173
+ 2. Configure VSCode settings:
174
+ ```json
175
+ {
176
+ "remote.SSH.configFile": "~/.ssh/vscode/config",
177
+ "remote.SSH.connectTimeout": 90
178
+ }
179
+ ```
180
+
181
+ ## Usage
182
+
183
+ ### Command Line
184
+
185
+ ```bash
186
+ # Basic usage (uses default vscode profile, port 22, and eu-west-1 region)
187
+ uvx cloudx-proxy i-0123456789abcdef0
188
+
189
+ # With custom port
190
+ uvx cloudx-proxy i-0123456789abcdef0 2222
191
+
192
+ # With custom profile
193
+ uvx cloudx-proxy i-0123456789abcdef0 --profile myprofile
194
+
195
+ # With different region (overrides eu-west-1 default)
196
+ uvx cloudx-proxy i-0123456789abcdef0 --region us-east-1
197
+
198
+ # With AWS profile organizer environment
199
+ uvx cloudx-proxy i-0123456789abcdef0 --aws-env prod
200
+
201
+ # With custom SSH key
202
+ uvx cloudx-proxy i-0123456789abcdef0 --key-path ~/.ssh/custom_key.pub
203
+ ```
204
+
205
+ ### VSCode
206
+
207
+ 1. Click the "Remote Explorer" icon in the VSCode sidebar
208
+ 2. Select "SSH Targets" from the dropdown
209
+ 3. Your configured hosts will appear (e.g., cloudx-dev)
210
+ 4. Click the "+" icon next to a host to connect
211
+ 5. VSCode will handle the rest, using cloudX-proxy to establish the connection
212
+
213
+ ## AWS Permissions
214
+
215
+ The AWS user/role needs these permissions:
216
+
217
+ ```json
218
+ {
219
+ "Version": "2012-10-17",
220
+ "Statement": [
221
+ {
222
+ "Effect": "Allow",
223
+ "Action": [
224
+ "ec2:StartInstances",
225
+ "ec2:DescribeInstances",
226
+ "ssm:StartSession",
227
+ "ssm:DescribeInstanceInformation",
228
+ "ec2-instance-connect:SendSSHPublicKey"
229
+ ],
230
+ "Resource": "*"
231
+ }
232
+ ]
233
+ }
234
+ ```
235
+
236
+ ## Troubleshooting
237
+
238
+ 1. **Connection Timeout**
239
+ - Ensure the instance has the SSM agent installed and running
240
+ - Check that your AWS credentials have the required permissions
241
+ - Verify the instance ID is correct
242
+ - Increase the VSCode SSH timeout if needed
243
+
244
+ 2. **SSH Key Issues**
245
+ - Ensure the key pair exists in the correct location
246
+ - Check file permissions (600 for private key, 644 for public key)
247
+ - Verify the public key is being successfully pushed to the instance
248
+
249
+ 3. **AWS Configuration**
250
+ - Confirm AWS CLI is configured with valid credentials (default profile name is 'vscode')
251
+ - Default region is eu-west-1 if not specified in profile or command line
252
+ - If using AWS profile organizer, ensure your environment directory exists at `~/.aws/aws-envs/<environment>/`
253
+ - Verify the Session Manager plugin is installed correctly
254
+ - Check that the instance has the required IAM role for SSM
255
+
256
+ ## License
257
+
258
+ MIT License - see LICENSE file for details
@@ -0,0 +1,10 @@
1
+ cloudx_proxy/__init__.py,sha256=YfZd1x9PT_aGA4FGsNw1WwvWkfRKLy_9O93a_W2wtiE,187
2
+ cloudx_proxy/_version.py,sha256=fWRR5Orqc8dqtVKNeAfCqsDhc30HwoGblv4fyeGnKoY,417
3
+ cloudx_proxy/cli.py,sha256=bBcvqiKpsLY6cYt-OG8282RZuoSDwDgEdyehTAeeec0,1502
4
+ cloudx_proxy/core.py,sha256=j6CUKdg2Ikcoi-05ceXMGA_c1aGWBhN9_JevbkLkaUY,7383
5
+ cloudx_proxy-2025.3.0.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
6
+ cloudx_proxy-2025.3.0.dist-info/METADATA,sha256=I-ImXVJrHCT-tnl26xPK94FrtVwxZ-dgc7290pzp0rs,9527
7
+ cloudx_proxy-2025.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
+ cloudx_proxy-2025.3.0.dist-info/entry_points.txt,sha256=BugqsX1eJtZGC6b5ONbieB9To9go2RCQVXuzdN79lZQ,55
9
+ cloudx_proxy-2025.3.0.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
10
+ cloudx_proxy-2025.3.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cloudx-proxy = cloudx_proxy.cli:main
@@ -0,0 +1 @@
1
+ cloudx_proxy