cloudx-proxy 0.4.1__tar.gz → 0.4.2__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.
Files changed (23) hide show
  1. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/CHANGELOG.md +7 -0
  2. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/PKG-INFO +1 -1
  3. cloudx_proxy-0.4.2/cloudx_proxy/_1password.py +208 -0
  4. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy/_version.py +2 -2
  5. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/PKG-INFO +1 -1
  6. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/SOURCES.txt +1 -0
  7. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/.github/workflows/release.yml +0 -0
  8. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/.gitignore +0 -0
  9. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/.releaserc +0 -0
  10. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/CONTRIBUTING.md +0 -0
  11. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/LICENSE +0 -0
  12. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/README.md +0 -0
  13. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy/__init__.py +0 -0
  14. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy/cli.py +0 -0
  15. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy/core.py +0 -0
  16. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy/setup.py +0 -0
  17. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/dependency_links.txt +0 -0
  18. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/entry_points.txt +0 -0
  19. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/requires.txt +0 -0
  20. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/cloudx_proxy.egg-info/top_level.txt +0 -0
  21. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/package.json +0 -0
  22. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/pyproject.toml +0 -0
  23. {cloudx_proxy-0.4.1 → cloudx_proxy-0.4.2}/setup.cfg +0 -0
@@ -1,3 +1,10 @@
1
+ ## [0.4.2](https://github.com/easytocloud/cloudX-proxy/compare/v0.4.1...v0.4.2) (2025-03-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * added _1password.py ([421a95f](https://github.com/easytocloud/cloudX-proxy/commit/421a95f867c2c2b6ee3eea220d06cf00a5c8228c))
7
+
1
8
  ## [0.4.1](https://github.com/easytocloud/cloudX-proxy/compare/v0.4.0...v0.4.1) (2025-03-06)
2
9
 
3
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudx-proxy
3
- Version: 0.4.1
3
+ Version: 0.4.2
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,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
@@ -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.1'
21
- __version_tuple__ = version_tuple = (0, 4, 1)
20
+ __version__ = version = '0.4.2'
21
+ __version_tuple__ = version_tuple = (0, 4, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudx-proxy
3
- Version: 0.4.1
3
+ Version: 0.4.2
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
@@ -7,6 +7,7 @@ README.md
7
7
  package.json
8
8
  pyproject.toml
9
9
  .github/workflows/release.yml
10
+ cloudx_proxy/_1password.py
10
11
  cloudx_proxy/__init__.py
11
12
  cloudx_proxy/_version.py
12
13
  cloudx_proxy/cli.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes