cloudx-proxy 0.4.1__py3-none-any.whl → 0.4.3__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/_1password.py +208 -0
- cloudx_proxy/_version.py +2 -2
- cloudx_proxy/setup.py +42 -35
- {cloudx_proxy-0.4.1.dist-info → cloudx_proxy-0.4.3.dist-info}/METADATA +47 -16
- cloudx_proxy-0.4.3.dist-info/RECORD +12 -0
- cloudx_proxy-0.4.1.dist-info/RECORD +0 -11
- {cloudx_proxy-0.4.1.dist-info → cloudx_proxy-0.4.3.dist-info}/LICENSE +0 -0
- {cloudx_proxy-0.4.1.dist-info → cloudx_proxy-0.4.3.dist-info}/WHEEL +0 -0
- {cloudx_proxy-0.4.1.dist-info → cloudx_proxy-0.4.3.dist-info}/entry_points.txt +0 -0
- {cloudx_proxy-0.4.1.dist-info → cloudx_proxy-0.4.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
import os
|
2
|
+
import json
|
3
|
+
import subprocess
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
def check_1password_cli() -> tuple:
|
7
|
+
"""Check if 1Password CLI is installed and authenticated.
|
8
|
+
|
9
|
+
Returns:
|
10
|
+
tuple: (installed: bool, authenticated: bool, version: str)
|
11
|
+
"""
|
12
|
+
try:
|
13
|
+
# Check if 1Password CLI is installed
|
14
|
+
result = subprocess.run(
|
15
|
+
['op', '--version'],
|
16
|
+
capture_output=True,
|
17
|
+
text=True,
|
18
|
+
check=False
|
19
|
+
)
|
20
|
+
|
21
|
+
if result.returncode != 0:
|
22
|
+
return False, False, ""
|
23
|
+
|
24
|
+
version = result.stdout.strip()
|
25
|
+
|
26
|
+
# Check if 1Password CLI is authenticated
|
27
|
+
result = subprocess.run(
|
28
|
+
['op', 'account', 'list'],
|
29
|
+
capture_output=True,
|
30
|
+
text=True,
|
31
|
+
check=False
|
32
|
+
)
|
33
|
+
|
34
|
+
if result.returncode != 0:
|
35
|
+
return True, False, version
|
36
|
+
|
37
|
+
return True, True, version
|
38
|
+
|
39
|
+
except FileNotFoundError:
|
40
|
+
return False, False, ""
|
41
|
+
except Exception:
|
42
|
+
return False, False, ""
|
43
|
+
|
44
|
+
def check_ssh_agent(agent_sock_path: str) -> bool:
|
45
|
+
"""Check if 1Password SSH agent is running.
|
46
|
+
|
47
|
+
Args:
|
48
|
+
agent_sock_path: Path to the SSH agent socket
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
bool: True if agent is running
|
52
|
+
"""
|
53
|
+
try:
|
54
|
+
# Check if the socket file exists
|
55
|
+
if not os.path.exists(agent_sock_path):
|
56
|
+
return False
|
57
|
+
|
58
|
+
# Check if agent is active
|
59
|
+
env = os.environ.copy()
|
60
|
+
env['SSH_AUTH_SOCK'] = agent_sock_path
|
61
|
+
|
62
|
+
result = subprocess.run(
|
63
|
+
['ssh-add', '-l'],
|
64
|
+
env=env,
|
65
|
+
capture_output=True,
|
66
|
+
text=True,
|
67
|
+
check=False
|
68
|
+
)
|
69
|
+
|
70
|
+
if "Could not open a connection to your authentication agent" in result.stderr:
|
71
|
+
return False
|
72
|
+
|
73
|
+
return True
|
74
|
+
|
75
|
+
except Exception:
|
76
|
+
return False
|
77
|
+
|
78
|
+
def list_ssh_keys() -> list:
|
79
|
+
"""List SSH keys stored in 1Password.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
list: List of SSH key items
|
83
|
+
"""
|
84
|
+
try:
|
85
|
+
# List SSH keys in 1Password using the correct command - confusingly, the category is "SSH Key" where the OUTPUT show "SSH_KEY"
|
86
|
+
result = subprocess.run(
|
87
|
+
['op', 'item', 'list', '--categories', 'SSH Key', '--format=json'],
|
88
|
+
capture_output=True,
|
89
|
+
text=True,
|
90
|
+
check=False
|
91
|
+
)
|
92
|
+
|
93
|
+
if result.returncode != 0:
|
94
|
+
return []
|
95
|
+
|
96
|
+
items = json.loads(result.stdout)
|
97
|
+
return items
|
98
|
+
|
99
|
+
except Exception:
|
100
|
+
return []
|
101
|
+
|
102
|
+
def create_ssh_key(title: str, vault: str) -> tuple:
|
103
|
+
"""Create a new SSH key in 1Password.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
title: Title for the SSH key
|
107
|
+
vault: Vault ID to store the key in
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
tuple: (success: bool, public_key: str, item_id: str)
|
111
|
+
"""
|
112
|
+
try:
|
113
|
+
# Create a new SSH key in 1Password
|
114
|
+
result = subprocess.run(
|
115
|
+
[
|
116
|
+
'op', 'item', 'create',
|
117
|
+
'--category=ssh-key', # and yet a different way to specify the category
|
118
|
+
f'--title={title}',
|
119
|
+
f'--vault={vault}'
|
120
|
+
],
|
121
|
+
capture_output=True,
|
122
|
+
text=True,
|
123
|
+
check=False
|
124
|
+
)
|
125
|
+
|
126
|
+
if result.returncode != 0:
|
127
|
+
return False, "", ""
|
128
|
+
|
129
|
+
# Parse the output to extract the public key and item ID
|
130
|
+
output_lines = result.stdout.strip().split('\n')
|
131
|
+
item_id = ""
|
132
|
+
public_key = ""
|
133
|
+
|
134
|
+
for idx, line in enumerate(output_lines):
|
135
|
+
if line.startswith("ID:"):
|
136
|
+
item_id = line.split(":", 1)[1].strip()
|
137
|
+
|
138
|
+
# Check for "public key:" in the line
|
139
|
+
if "public key:" in line.lower():
|
140
|
+
public_key = line.split(":", 1)[1].strip()
|
141
|
+
|
142
|
+
# If we got the item ID but not the public key, try to get it separately
|
143
|
+
if item_id and not public_key:
|
144
|
+
result = subprocess.run(
|
145
|
+
['op', 'item', 'get', item_id, '--fields', 'public key'],
|
146
|
+
capture_output=True,
|
147
|
+
text=True,
|
148
|
+
check=False
|
149
|
+
)
|
150
|
+
|
151
|
+
if result.returncode == 0:
|
152
|
+
public_key = result.stdout.strip()
|
153
|
+
|
154
|
+
return item_id and public_key, public_key, item_id
|
155
|
+
|
156
|
+
except Exception:
|
157
|
+
return False, "", ""
|
158
|
+
|
159
|
+
def get_vaults() -> list:
|
160
|
+
"""Get list of available 1Password vaults.
|
161
|
+
|
162
|
+
Returns:
|
163
|
+
list: List of vault objects with 'id' and 'name' keys
|
164
|
+
"""
|
165
|
+
try:
|
166
|
+
result = subprocess.run(
|
167
|
+
['op', 'vault', 'list', '--format=json'],
|
168
|
+
capture_output=True,
|
169
|
+
text=True,
|
170
|
+
check=False
|
171
|
+
)
|
172
|
+
|
173
|
+
if result.returncode != 0:
|
174
|
+
return []
|
175
|
+
|
176
|
+
vaults = json.loads(result.stdout)
|
177
|
+
return vaults
|
178
|
+
|
179
|
+
except Exception:
|
180
|
+
return []
|
181
|
+
|
182
|
+
def save_public_key(public_key: str, key_path: str) -> bool:
|
183
|
+
"""Save the public key to a file with proper permissions.
|
184
|
+
|
185
|
+
Args:
|
186
|
+
public_key: The public key content
|
187
|
+
key_path: Path to save the public key
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
bool: True if successful
|
191
|
+
"""
|
192
|
+
try:
|
193
|
+
# Create parent directories if needed
|
194
|
+
os.makedirs(os.path.dirname(key_path), exist_ok=True)
|
195
|
+
|
196
|
+
# Write the public key
|
197
|
+
with open(key_path, 'w') as f:
|
198
|
+
f.write(public_key)
|
199
|
+
|
200
|
+
# Set permissions (644) on Unix-like systems
|
201
|
+
if os.name != 'nt': # Not Windows
|
202
|
+
import stat
|
203
|
+
os.chmod(key_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IROTH | stat.S_IRGRP)
|
204
|
+
|
205
|
+
return True
|
206
|
+
|
207
|
+
except Exception:
|
208
|
+
return False
|
cloudx_proxy/_version.py
CHANGED
cloudx_proxy/setup.py
CHANGED
@@ -383,38 +383,56 @@ class CloudXSetup:
|
|
383
383
|
IdentitiesOnly yes
|
384
384
|
"""
|
385
385
|
|
386
|
-
def
|
387
|
-
"""Build
|
386
|
+
def _build_environment_config(self, cloudx_env: str) -> str:
|
387
|
+
"""Build an environment-wide configuration block with all common settings.
|
388
388
|
|
389
389
|
Args:
|
390
390
|
cloudx_env: CloudX environment
|
391
|
-
hostname: Hostname for the instance
|
392
|
-
instance_id: EC2 instance ID (None for wildcard entries)
|
393
|
-
include_proxy: Whether to include the ProxyCommand (default: True)
|
394
391
|
|
395
392
|
Returns:
|
396
|
-
str: Complete
|
393
|
+
str: Complete environment configuration block
|
397
394
|
"""
|
398
|
-
host_pattern = hostname if hostname else "*"
|
399
395
|
host_entry = f"""
|
400
|
-
Host cloudx-{cloudx_env}
|
401
|
-
|
402
|
-
# Add HostName only for specific hosts, not for wildcard entries
|
403
|
-
if instance_id:
|
404
|
-
host_entry += f""" HostName {instance_id}
|
405
|
-
"""
|
406
|
-
host_entry += """ User ec2-user
|
396
|
+
Host cloudx-{cloudx_env}-*
|
397
|
+
User ec2-user
|
407
398
|
"""
|
408
399
|
# Add authentication configuration
|
409
400
|
host_entry += self._build_auth_config()
|
410
401
|
|
411
|
-
# Add
|
412
|
-
|
413
|
-
|
402
|
+
# Add ProxyCommand
|
403
|
+
host_entry += f""" ProxyCommand {self._build_proxy_command()}
|
404
|
+
"""
|
405
|
+
|
406
|
+
# Add SSH multiplexing configuration
|
407
|
+
control_path = "~/.ssh/control/%r@%h:%p"
|
408
|
+
if platform.system() == 'Windows':
|
409
|
+
# Use forward slashes for Windows as well, SSH client will handle conversion
|
410
|
+
control_path = "~/.ssh/control/%r@%h:%p"
|
411
|
+
|
412
|
+
host_entry += f""" TCPKeepAlive yes
|
413
|
+
ControlMaster auto
|
414
|
+
ControlPath {control_path}
|
415
|
+
ControlPersist 4h
|
414
416
|
"""
|
415
417
|
|
416
418
|
return host_entry
|
417
419
|
|
420
|
+
def _build_host_config(self, cloudx_env: str, hostname: str, instance_id: str) -> str:
|
421
|
+
"""Build a minimal host configuration block that inherits from the environment.
|
422
|
+
|
423
|
+
Args:
|
424
|
+
cloudx_env: CloudX environment
|
425
|
+
hostname: Hostname for the instance
|
426
|
+
instance_id: EC2 instance ID
|
427
|
+
|
428
|
+
Returns:
|
429
|
+
str: Minimal host configuration block with only hostname
|
430
|
+
"""
|
431
|
+
return f"""
|
432
|
+
Host cloudx-{cloudx_env}-{hostname}
|
433
|
+
HostName {instance_id}
|
434
|
+
"""
|
435
|
+
|
418
436
|
def _add_host_entry(self, cloudx_env: str, instance_id: str, hostname: str, current_config: str) -> bool:
|
419
437
|
"""Add settings to a specific host entry.
|
420
438
|
|
@@ -566,24 +584,13 @@ Host cloudx-{cloudx_env}-{host_pattern}
|
|
566
584
|
|
567
585
|
# Build base configuration with wildcard hostname pattern
|
568
586
|
# Start with a header comment
|
569
|
-
base_config = "# cloudx-proxy SSH Configuration
|
570
|
-
|
571
|
-
# Add base host pattern with wildcard
|
572
|
-
base_config += self._build_host_config(cloudx_env, None, None, include_proxy=True)
|
573
|
-
|
574
|
-
# Add SSH multiplexing configuration
|
575
|
-
control_path = "~/.ssh/control/%r@%h:%p"
|
576
|
-
if platform.system() == 'Windows':
|
577
|
-
# Use forward slashes for Windows as well, SSH client will handle conversion
|
578
|
-
control_path = "~/.ssh/control/%r@%h:%p"
|
579
|
-
|
580
|
-
base_config += f""" TCPKeepAlive yes
|
581
|
-
ControlMaster auto
|
582
|
-
ControlPath {control_path}
|
583
|
-
ControlPersist 4h
|
584
|
-
|
587
|
+
base_config = """# cloudx-proxy SSH Configuration
|
588
|
+
# Environment configuration with settings applied to all hosts in this environment
|
585
589
|
"""
|
586
590
|
|
591
|
+
# Add environment-wide configuration with all common settings
|
592
|
+
base_config += self._build_environment_config(cloudx_env)
|
593
|
+
|
587
594
|
# If file exists, append the new config, otherwise create it
|
588
595
|
if self.ssh_config_file.exists():
|
589
596
|
with open(self.ssh_config_file, 'a') as f:
|
@@ -598,9 +605,9 @@ Host cloudx-{cloudx_env}-{host_pattern}
|
|
598
605
|
self.ssh_config_file.chmod(stat.S_IRUSR | stat.S_IWUSR) # 600 permissions (owner read/write)
|
599
606
|
self.print_status("Set config file permissions to 600", True, 2)
|
600
607
|
|
601
|
-
# Add specific host entry
|
608
|
+
# Add specific host entry - only specifying the hostname
|
602
609
|
self.print_status(f"Adding host entry for cloudx-{cloudx_env}-{hostname}", None, 2)
|
603
|
-
host_entry = self._build_host_config(cloudx_env, hostname, instance_id
|
610
|
+
host_entry = self._build_host_config(cloudx_env, hostname, instance_id)
|
604
611
|
with open(self.ssh_config_file, 'a') as f:
|
605
612
|
f.write(host_entry)
|
606
613
|
self.print_status("Host entry added", True, 2)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: cloudx-proxy
|
3
|
-
Version: 0.4.
|
3
|
+
Version: 0.4.3
|
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
|
@@ -112,6 +112,15 @@ uvx cloudx-proxy setup --profile myprofile --ssh-key mykey
|
|
112
112
|
|
113
113
|
# Setup with AWS environment
|
114
114
|
uvx cloudx-proxy setup --aws-env prod
|
115
|
+
|
116
|
+
# Setup with custom SSH config location
|
117
|
+
uvx cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config
|
118
|
+
|
119
|
+
# Setup with 1Password integration
|
120
|
+
uvx cloudx-proxy setup --1password
|
121
|
+
|
122
|
+
# Combine options
|
123
|
+
uvx cloudx-proxy setup --profile myprofile --ssh-key mykey --ssh-config ~/.ssh/cloudx/config --1password --aws-env prod
|
115
124
|
```
|
116
125
|
|
117
126
|
The setup command will:
|
@@ -123,13 +132,16 @@ The setup command will:
|
|
123
132
|
|
124
133
|
2. Manage SSH Keys:
|
125
134
|
- Creates new SSH key pair if needed
|
126
|
-
-
|
127
|
-
* Using 1Password SSH agent
|
128
|
-
*
|
135
|
+
- Fully supports 1Password integration:
|
136
|
+
* Using 1Password SSH agent via `--1password` flag
|
137
|
+
* Creates keys directly in 1Password's secure vault
|
138
|
+
* Only public keys are exported to the filesystem
|
139
|
+
* Follows SSH best practices using public keys to limit authentication attempts
|
129
140
|
|
130
141
|
3. Configure SSH:
|
131
|
-
- Creates ~/.ssh/vscode/config
|
132
|
-
-
|
142
|
+
- Creates SSH configs with proper settings (default: ~/.ssh/vscode/config)
|
143
|
+
- Custom config location can be specified with `--ssh-config`
|
144
|
+
- Sets up optimized environment-specific configurations
|
133
145
|
- Configures ProxyCommand with all necessary parameters
|
134
146
|
- Ensures main ~/.ssh/config includes the configuration
|
135
147
|
|
@@ -150,12 +162,18 @@ Will create a configuration like this:
|
|
150
162
|
|
151
163
|
```
|
152
164
|
# Base environment config (created once per environment)
|
165
|
+
# Environment-wide configuration
|
153
166
|
Host cloudx-dev-*
|
154
167
|
User ec2-user
|
155
168
|
IdentityFile ~/.ssh/vscode/mykey
|
169
|
+
IdentitiesOnly yes
|
156
170
|
ProxyCommand uvx cloudx-proxy connect %h %p --profile myprofile --ssh-key mykey
|
171
|
+
TCPKeepAlive yes
|
172
|
+
ControlMaster auto
|
173
|
+
ControlPath ~/.ssh/control/%r@%h:%p
|
174
|
+
ControlPersist 4h
|
157
175
|
|
158
|
-
#
|
176
|
+
# Minimal host entry (inherits all settings from environment config)
|
159
177
|
Host cloudx-dev-myserver
|
160
178
|
HostName i-0123456789abcdef0
|
161
179
|
```
|
@@ -173,17 +191,19 @@ In these examples, ssh will use cloudx-proxy to connect to AWS with the `myprofi
|
|
173
191
|
VSCode will be able to connect to the instance using the same SSH configuration.
|
174
192
|
|
175
193
|
### SSH Configuration Details
|
176
|
-
The setup command creates:
|
194
|
+
The setup command creates an optimized SSH configuration structure:
|
177
195
|
|
178
196
|
1. A base configuration for each environment (cloudx-{env}-*) with:
|
179
197
|
- User and key settings
|
180
|
-
- 1Password integration if selected
|
198
|
+
- 1Password SSH agent integration if selected
|
181
199
|
- ProxyCommand with appropriate parameters
|
200
|
+
- SSH multiplexing for better performance
|
201
|
+
- TCP keepalive for connection stability
|
182
202
|
|
183
|
-
2.
|
203
|
+
2. Minimal host entries for each instance:
|
184
204
|
- Uses consistent naming (cloudx-{env}-hostname)
|
185
|
-
-
|
186
|
-
- Inherits environment-level settings
|
205
|
+
- Only contains the HostName directive for the instance ID
|
206
|
+
- Inherits all environment-level settings automatically
|
187
207
|
|
188
208
|
When adding new instances to an existing environment, you can choose to:
|
189
209
|
- Override the environment configuration with new settings
|
@@ -211,7 +231,9 @@ uvx cloudx-proxy setup [OPTIONS]
|
|
211
231
|
|
212
232
|
Options:
|
213
233
|
- `--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.
|
214
|
-
- `--ssh-key` (default: vscode): Name of the SSH key to create/use. The key will be stored in
|
234
|
+
- `--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.
|
235
|
+
- `--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.
|
236
|
+
- `--1password` (flag): Enable 1Password SSH agent integration. Creates keys directly in 1Password and configures SSH to use the 1Password SSH agent.
|
215
237
|
- `--aws-env` (optional): AWS environment directory to use. If specified, AWS configuration and credentials will be read from ~/.aws/aws-envs/{env}/.
|
216
238
|
|
217
239
|
Example usage:
|
@@ -222,8 +244,11 @@ uvx cloudx-proxy setup
|
|
222
244
|
# Setup with custom profile and key
|
223
245
|
uvx cloudx-proxy setup --profile myprofile --ssh-key mykey
|
224
246
|
|
225
|
-
# Setup with
|
226
|
-
uvx cloudx-proxy setup --
|
247
|
+
# Setup with custom SSH config and 1Password integration
|
248
|
+
uvx cloudx-proxy setup --ssh-config ~/.ssh/cloudx/config --1password
|
249
|
+
|
250
|
+
# Complete setup with all options
|
251
|
+
uvx cloudx-proxy setup --profile myprofile --ssh-key mykey --ssh-config ~/.ssh/cloudx/config --1password --aws-env prod
|
227
252
|
```
|
228
253
|
|
229
254
|
#### Connect Command
|
@@ -238,6 +263,7 @@ Arguments:
|
|
238
263
|
Options:
|
239
264
|
- `--profile` (default: vscode): AWS profile to use. Should match the profile used in setup.
|
240
265
|
- `--ssh-key` (default: vscode): Name of the SSH key to use. Should match the key name used in setup.
|
266
|
+
- `--ssh-config` (optional): Path to the SSH config file to use. If provided during setup, should match here.
|
241
267
|
- `--region` (optional): AWS region to use. If not specified, uses the region from the AWS profile.
|
242
268
|
- `--aws-env` (optional): AWS environment directory to use. Should match the environment used in setup.
|
243
269
|
|
@@ -303,12 +329,17 @@ These permissions are required to bootstrap the instance, so that after creation
|
|
303
329
|
- Check that your AWS credentials have the required permissions
|
304
330
|
- Verify the instance ID is correct
|
305
331
|
- Increase the VSCode SSH timeout if needed
|
332
|
+
- Check if the instance is starting up (can take several minutes)
|
306
333
|
|
307
334
|
3. **SSH Key Issues**
|
308
335
|
- If using 1Password SSH agent, verify agent is running (~/.1password/agent.sock exists)
|
309
336
|
- Check file permissions (600 for private key, 644 for public key)
|
310
337
|
- Verify the public key is being successfully pushed to the instance
|
311
|
-
- For
|
338
|
+
- For 1Password-managed keys, make sure:
|
339
|
+
* 1Password CLI is installed and authenticated (`op account list` works)
|
340
|
+
* SSH agent is enabled in 1Password settings
|
341
|
+
* Keys are added to the SSH agent in 1Password
|
342
|
+
* The key is visible with `op item list --categories "SSH Key"`
|
312
343
|
|
313
344
|
4. **AWS Configuration**
|
314
345
|
- 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=zJwW9_MgFPmVYNh3YnSsdJ4y2EqGvu1bzYeID1Rrd0A,511
|
4
|
+
cloudx_proxy/cli.py,sha256=kdrZydxL94BJrv6NnjIcceRqhoonBzMIx4vfm1Wl7qc,4104
|
5
|
+
cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
|
6
|
+
cloudx_proxy/setup.py,sha256=MBjeoyDs_KhENxifZbIpG1u016af-sJhq18tCUM6EmI,33402
|
7
|
+
cloudx_proxy-0.4.3.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
8
|
+
cloudx_proxy-0.4.3.dist-info/METADATA,sha256=6GHrg_AaK1C9_hwyVfx7Sr1ihORwQ9r8d_b1N5jPXr4,15893
|
9
|
+
cloudx_proxy-0.4.3.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
10
|
+
cloudx_proxy-0.4.3.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
11
|
+
cloudx_proxy-0.4.3.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
12
|
+
cloudx_proxy-0.4.3.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
cloudx_proxy/__init__.py,sha256=ZZ2O_m9OFJm18AxMSuYJt4UjSuSqyJlYRaZMoets498,61
|
2
|
-
cloudx_proxy/_version.py,sha256=yF2DwGUoQKNnLhAbpZX8kCQKjw77EZzhRk7_OTftets,511
|
3
|
-
cloudx_proxy/cli.py,sha256=kdrZydxL94BJrv6NnjIcceRqhoonBzMIx4vfm1Wl7qc,4104
|
4
|
-
cloudx_proxy/core.py,sha256=RF3bX5MQiokRKjYEPnfWdKywGdtoVUvV2xZqm9uOl1g,8135
|
5
|
-
cloudx_proxy/setup.py,sha256=jvv7ibJQ8svyjYYeVKwGa70L7RV2W7yS7JXEvKed3wI,33339
|
6
|
-
cloudx_proxy-0.4.1.dist-info/LICENSE,sha256=i7P2OR4zsJYsMWcCUDe_B9ZfGi9bU0K5I2nKfDrW_N8,1068
|
7
|
-
cloudx_proxy-0.4.1.dist-info/METADATA,sha256=wFL6lV-shLLfI6cn8H5ZItIF944-TrX67LJC0Ml-muc,14037
|
8
|
-
cloudx_proxy-0.4.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
9
|
-
cloudx_proxy-0.4.1.dist-info/entry_points.txt,sha256=HGt743N2lVlKd7O1qWq3C0aEHyS5PjPnxzDHh7hwtSg,54
|
10
|
-
cloudx_proxy-0.4.1.dist-info/top_level.txt,sha256=2wtEote1db21j-VvkCJFfT-dLlauuG5indjggYh3xDg,13
|
11
|
-
cloudx_proxy-0.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|