snapctl 0.49.2__tar.gz → 0.49.4__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.
Potentially problematic release.
This version of snapctl might be problematic. Click here for more details.
- {snapctl-0.49.2 → snapctl-0.49.4}/PKG-INFO +7 -2
- {snapctl-0.49.2 → snapctl-0.49.4}/README.md +6 -1
- {snapctl-0.49.2 → snapctl-0.49.4}/pyproject.toml +1 -1
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/byows.py +137 -72
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/config/constants.py +3 -1
- snapctl-0.49.4/snapctl/data/releases/beta-0.49.3.mdx +7 -0
- snapctl-0.49.4/snapctl/data/releases/beta-0.49.4.mdx +8 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/main.py +3 -1
- {snapctl-0.49.2 → snapctl-0.49.4}/LICENSE +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/__main__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/byogs.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/byosnap.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/game.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/generate.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/release_notes.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/commands/snapend.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/config/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/config/endpoints.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/config/hashes.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/profiles/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/profiles/snapser-byosnap-profile.json +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/profiles/snapser-byosnap-profile.yaml +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/profiles/snapser-byosnap-profile.yml +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.46.0.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.46.4.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.47.0.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.47.1.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.47.2.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.48.0.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.49.0.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.49.1.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/data/releases/beta-0.49.2.mdx +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/types/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/types/definitions.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/utils/__init__.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/utils/echo.py +0 -0
- {snapctl-0.49.2 → snapctl-0.49.4}/snapctl/utils/helper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: snapctl
|
|
3
|
-
Version: 0.49.
|
|
3
|
+
Version: 0.49.4
|
|
4
4
|
Summary: Snapser CLI Tool
|
|
5
5
|
Author: Ajinkya Apte
|
|
6
6
|
Author-email: aj@snapser.com
|
|
@@ -34,10 +34,13 @@ Snapctl will be the best way for game studios to integrate Snapser into their bu
|
|
|
34
34
|
1. Renamed SDK type `server` to `api-key` to be consistent with the Snapser Web app.
|
|
35
35
|
|
|
36
36
|
### Features
|
|
37
|
-
1. Added support for Bring your own Workstation commands.
|
|
37
|
+
1. Added support for Bring your own Workstation commands. This enables local debugging for your BYOSnaps while clients continue to access your cloud Snapend APIs.
|
|
38
38
|
```bash
|
|
39
39
|
snapctl byows attach --snapend-id $snapend_id --byosnap-id $byosnap_id --http-port $http_port
|
|
40
40
|
```
|
|
41
|
+
```bash
|
|
42
|
+
snapctl byows reset --snapend-id $snapend_id
|
|
43
|
+
```
|
|
41
44
|
|
|
42
45
|
## Requirements
|
|
43
46
|
### Python 3.X and Pip
|
|
@@ -845,4 +848,6 @@ snapctl generate credentials --category "ecr" --out-path $output_path
|
|
|
845
848
|
| Error Code | Description |
|
|
846
849
|
|------------|----------------------------------------------------------|
|
|
847
850
|
| 95 | Generic byows error |
|
|
851
|
+
| 96 | Byows attach error |
|
|
852
|
+
| 97 | Byows reset error |
|
|
848
853
|
|
|
@@ -14,10 +14,13 @@ Snapctl will be the best way for game studios to integrate Snapser into their bu
|
|
|
14
14
|
1. Renamed SDK type `server` to `api-key` to be consistent with the Snapser Web app.
|
|
15
15
|
|
|
16
16
|
### Features
|
|
17
|
-
1. Added support for Bring your own Workstation commands.
|
|
17
|
+
1. Added support for Bring your own Workstation commands. This enables local debugging for your BYOSnaps while clients continue to access your cloud Snapend APIs.
|
|
18
18
|
```bash
|
|
19
19
|
snapctl byows attach --snapend-id $snapend_id --byosnap-id $byosnap_id --http-port $http_port
|
|
20
20
|
```
|
|
21
|
+
```bash
|
|
22
|
+
snapctl byows reset --snapend-id $snapend_id
|
|
23
|
+
```
|
|
21
24
|
|
|
22
25
|
## Requirements
|
|
23
26
|
### Python 3.X and Pip
|
|
@@ -825,3 +828,5 @@ snapctl generate credentials --category "ecr" --out-path $output_path
|
|
|
825
828
|
| Error Code | Description |
|
|
826
829
|
|------------|----------------------------------------------------------|
|
|
827
830
|
| 95 | Generic byows error |
|
|
831
|
+
| 96 | Byows attach error |
|
|
832
|
+
| 97 | Byows reset error |
|
|
@@ -6,23 +6,26 @@ import platform
|
|
|
6
6
|
import subprocess
|
|
7
7
|
import shutil
|
|
8
8
|
import time
|
|
9
|
-
import
|
|
10
|
-
|
|
9
|
+
import signal
|
|
10
|
+
import functools
|
|
11
|
+
import sys
|
|
11
12
|
from typing import Union
|
|
12
13
|
import threading
|
|
13
14
|
import requests
|
|
14
15
|
from requests.exceptions import RequestException, HTTPError
|
|
15
16
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
16
17
|
from snapctl.config.constants import SERVER_CALL_TIMEOUT, SNAPCTL_INPUT_ERROR, \
|
|
17
|
-
SNAPCTL_BYOWS_GENERIC_ERROR, SNAPCTL_DEPENDENCY_MISSING
|
|
18
|
+
SNAPCTL_BYOWS_GENERIC_ERROR, SNAPCTL_DEPENDENCY_MISSING, \
|
|
19
|
+
SNAPCTL_BYOWS_ATTACH_ERROR, SNAPCTL_BYOWS_RESET_ERROR
|
|
18
20
|
from snapctl.utils.helper import snapctl_error, snapctl_success, get_dot_snapser_dir
|
|
19
21
|
from snapctl.utils.echo import info, warning
|
|
20
22
|
|
|
23
|
+
|
|
21
24
|
class Byows:
|
|
22
25
|
"""
|
|
23
26
|
CLI commands exposed for a Bring your own Workstation
|
|
24
27
|
"""
|
|
25
|
-
SUBCOMMANDS = ['attach']
|
|
28
|
+
SUBCOMMANDS = ['attach', 'reset']
|
|
26
29
|
SSH_FILE = 'id_snapser_byows_attach_ed25519'
|
|
27
30
|
PORT_FORWARD_TTL = 3600 * 24 * 7
|
|
28
31
|
BYOWS_ENV_FILE = 'byows_env_setup'
|
|
@@ -41,6 +44,7 @@ class Byows:
|
|
|
41
44
|
self.byosnap_id: Union[str, None] = byosnap_id
|
|
42
45
|
self.http_port: Union[int, None] = http_port
|
|
43
46
|
self.grpc_port: Union[int, None] = grpc_port
|
|
47
|
+
self._ssh_process = None
|
|
44
48
|
self.validate_input()
|
|
45
49
|
|
|
46
50
|
def validate_input(self) -> None:
|
|
@@ -74,9 +78,14 @@ class Byows:
|
|
|
74
78
|
snapctl_error(
|
|
75
79
|
message="Missing Input. One of --http-port=$your_local_server_port or --grpc-port=$your_local_server_port is required.",
|
|
76
80
|
code=SNAPCTL_INPUT_ERROR)
|
|
77
|
-
|
|
81
|
+
elif self.subcommand == 'reset':
|
|
82
|
+
if self.snapend_id is None or self.snapend_id == '':
|
|
83
|
+
snapctl_error(
|
|
84
|
+
message="Missing Input --snapend-id=$your_snapend_id",
|
|
85
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
78
86
|
|
|
79
87
|
# Static methods
|
|
88
|
+
|
|
80
89
|
@staticmethod
|
|
81
90
|
def stream_output(pipe):
|
|
82
91
|
'''
|
|
@@ -90,11 +99,12 @@ class Byows:
|
|
|
90
99
|
def _get_export_commands(snap_ids, port):
|
|
91
100
|
'''
|
|
92
101
|
Generate export commands for the given snap IDs and port.
|
|
102
|
+
Replace hyphens with underscores in environment variable names.
|
|
93
103
|
'''
|
|
94
104
|
env_vars = []
|
|
95
105
|
|
|
96
106
|
for snap_id in snap_ids:
|
|
97
|
-
upper_id = snap_id.upper()
|
|
107
|
+
upper_id = snap_id.upper().replace("-", "_")
|
|
98
108
|
env_vars.append(f"SNAPEND_{upper_id}_GRPC_URL=localhost:{port}")
|
|
99
109
|
env_vars.append(
|
|
100
110
|
f"SNAPEND_{upper_id}_HTTP_URL=http://localhost:{port}")
|
|
@@ -112,11 +122,12 @@ class Byows:
|
|
|
112
122
|
def _generate_env_file(snap_ids, port):
|
|
113
123
|
'''
|
|
114
124
|
Generate an environment file with the given snap IDs and port.
|
|
125
|
+
Replace hyphens with underscores in environment variable names.
|
|
115
126
|
'''
|
|
116
127
|
env_lines = []
|
|
117
128
|
|
|
118
129
|
for snap_id in snap_ids:
|
|
119
|
-
upper_id = snap_id.upper()
|
|
130
|
+
upper_id = snap_id.upper().replace("-", "_")
|
|
120
131
|
env_lines.append(
|
|
121
132
|
f"export SNAPEND_{upper_id}_GRPC_URL=localhost:{port}")
|
|
122
133
|
env_lines.append(
|
|
@@ -174,6 +185,58 @@ class Byows:
|
|
|
174
185
|
return f"HTTP Error {http_err.response.status_code}: {http_err.response.reason}\nResponse: {response.text.strip()}"
|
|
175
186
|
|
|
176
187
|
# Private methods
|
|
188
|
+
def _terminate_ssh_process(self):
|
|
189
|
+
if hasattr(self, "_ssh_process") and self._ssh_process:
|
|
190
|
+
try:
|
|
191
|
+
self._ssh_process.terminate()
|
|
192
|
+
if self._ssh_process.poll() is None:
|
|
193
|
+
self._ssh_process.wait(timeout=5)
|
|
194
|
+
except subprocess.TimeoutExpired:
|
|
195
|
+
warning("SSH process did not shut down gracefully.")
|
|
196
|
+
|
|
197
|
+
def _cleanup_files(self):
|
|
198
|
+
try:
|
|
199
|
+
dot_snapser_dir = get_dot_snapser_dir()
|
|
200
|
+
id_file = dot_snapser_dir / Byows.SSH_FILE
|
|
201
|
+
pub_file = dot_snapser_dir / f"{Byows.SSH_FILE}.pub"
|
|
202
|
+
if id_file.exists():
|
|
203
|
+
id_file.unlink()
|
|
204
|
+
if pub_file.exists():
|
|
205
|
+
pub_file.unlink()
|
|
206
|
+
except Exception as e:
|
|
207
|
+
warning(f"Cleanup warning: Failed to delete SSH key files – {e}")
|
|
208
|
+
|
|
209
|
+
def _handle_signal(self, signum, frame):
|
|
210
|
+
print(f"\nReceived signal {signum}. Cleaning up...", flush=True)
|
|
211
|
+
self._terminate_ssh_process()
|
|
212
|
+
self._cleanup_files()
|
|
213
|
+
try:
|
|
214
|
+
url = f"{self.base_url}/v1/snapser-api/byows/snapends/" + \
|
|
215
|
+
f"{self.snapend_id}/snaps/{self.byosnap_id}/enabled"
|
|
216
|
+
res = requests.put(
|
|
217
|
+
url, headers={'api-key': self.api_key}, json=False, timeout=SERVER_CALL_TIMEOUT)
|
|
218
|
+
res.raise_for_status()
|
|
219
|
+
info('Forwarding disabled')
|
|
220
|
+
except HTTPError as http_err:
|
|
221
|
+
snapctl_error(
|
|
222
|
+
message=Byows._format_portal_http_error(
|
|
223
|
+
"Unable to disable BYOWs", http_err, res),
|
|
224
|
+
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
225
|
+
)
|
|
226
|
+
except RequestException as req_err:
|
|
227
|
+
warning(
|
|
228
|
+
f"Response Status Code: {res.status_code}, Body: {res.text}")
|
|
229
|
+
snapctl_error(
|
|
230
|
+
message=f"Request Exception: Unable to disable BYOWs {req_err}",
|
|
231
|
+
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
232
|
+
)
|
|
233
|
+
except Exception as e:
|
|
234
|
+
snapctl_error(
|
|
235
|
+
message=f"Unexpected error occurred: {e}",
|
|
236
|
+
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
237
|
+
)
|
|
238
|
+
sys.exit(0)
|
|
239
|
+
|
|
177
240
|
def _setup_port_forward(
|
|
178
241
|
self, private_key, public_key, snapend_id, snap_id, port, reverse_port, reverse_grpc_port,
|
|
179
242
|
incoming_http, incoming_grpc, outgoing_http, snap_ids, ssh_connect_addr) -> bool:
|
|
@@ -220,7 +283,7 @@ class Byows:
|
|
|
220
283
|
ssh_command = [
|
|
221
284
|
'ssh',
|
|
222
285
|
'-q',
|
|
223
|
-
'-4',
|
|
286
|
+
'-4', # use IPv4
|
|
224
287
|
'-o', 'ServerAliveInterval=60',
|
|
225
288
|
'-o', 'StrictHostKeyChecking=no',
|
|
226
289
|
'-o', 'UserKnownHostsFile=/dev/null',
|
|
@@ -231,12 +294,13 @@ class Byows:
|
|
|
231
294
|
'-R', f'{reverse_port}:localhost:{incoming_http}',
|
|
232
295
|
]
|
|
233
296
|
if incoming_grpc:
|
|
234
|
-
ssh_command += ['-R',
|
|
297
|
+
ssh_command += ['-R',
|
|
298
|
+
f'{reverse_grpc_port}:localhost:{incoming_grpc}']
|
|
235
299
|
ssh_command += [ssh_host]
|
|
236
300
|
|
|
237
|
-
process = None
|
|
301
|
+
# process = None
|
|
238
302
|
try:
|
|
239
|
-
|
|
303
|
+
self._ssh_process = subprocess.Popen(
|
|
240
304
|
ssh_command,
|
|
241
305
|
shell=False,
|
|
242
306
|
stdout=subprocess.PIPE,
|
|
@@ -247,9 +311,9 @@ class Byows:
|
|
|
247
311
|
timeout_seconds = 5
|
|
248
312
|
start_time = time.time()
|
|
249
313
|
while True:
|
|
250
|
-
if
|
|
314
|
+
if self._ssh_process.poll() is not None:
|
|
251
315
|
# Process exited early — likely an error
|
|
252
|
-
stderr_output =
|
|
316
|
+
stderr_output = self._ssh_process.stderr.read().decode().strip()
|
|
253
317
|
if stderr_output:
|
|
254
318
|
info(f"[SSH Error] {stderr_output}")
|
|
255
319
|
else:
|
|
@@ -263,60 +327,16 @@ class Byows:
|
|
|
263
327
|
|
|
264
328
|
# Start background thread to stream live stderr
|
|
265
329
|
threading.Thread(target=Byows.stream_output, args=(
|
|
266
|
-
|
|
330
|
+
self._ssh_process.stderr,), daemon=True).start()
|
|
267
331
|
|
|
268
332
|
# Now block for the full tunnel lifetime
|
|
269
|
-
|
|
333
|
+
self._ssh_process.wait(timeout=Byows.PORT_FORWARD_TTL)
|
|
270
334
|
except KeyboardInterrupt:
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
process.wait(timeout=5)
|
|
274
|
-
except subprocess.TimeoutExpired:
|
|
275
|
-
warning('SSH process did not shut down gracefully.')
|
|
276
|
-
|
|
277
|
-
info('Shutting down port forward...')
|
|
278
|
-
|
|
279
|
-
try:
|
|
280
|
-
url = f"{self.base_url}/v1/snapser-api/byows/snapends/" + \
|
|
281
|
-
f"{self.snapend_id}/snaps/{self.byosnap_id}/enabled"
|
|
282
|
-
res = requests.put(
|
|
283
|
-
url, headers={'api-key': self.api_key}, json=False, timeout=SERVER_CALL_TIMEOUT)
|
|
284
|
-
res.raise_for_status()
|
|
285
|
-
info('Forwarding disabled')
|
|
286
|
-
except HTTPError as http_err:
|
|
287
|
-
snapctl_error(
|
|
288
|
-
message=Byows._format_portal_http_error(
|
|
289
|
-
"Unable to disable BYOWs", http_err, res),
|
|
290
|
-
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
291
|
-
)
|
|
292
|
-
return False
|
|
293
|
-
except RequestException as req_err:
|
|
294
|
-
warning(
|
|
295
|
-
f"Response Status Code: {res.status_code}, Body: {res.text}")
|
|
296
|
-
snapctl_error(
|
|
297
|
-
message=f"Request Exception: Unable to disable BYOWs {req_err}",
|
|
298
|
-
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
299
|
-
)
|
|
300
|
-
return False
|
|
301
|
-
except Exception as e:
|
|
302
|
-
snapctl_error(
|
|
303
|
-
message=f"Unexpected error occurred: {e}",
|
|
304
|
-
code=SNAPCTL_BYOWS_GENERIC_ERROR
|
|
305
|
-
)
|
|
306
|
-
return False
|
|
307
|
-
|
|
335
|
+
self._handle_signal(signal.SIGINT, None)
|
|
336
|
+
return False
|
|
308
337
|
except Exception as e:
|
|
309
338
|
print('Error running SSH command:', e)
|
|
310
339
|
return False
|
|
311
|
-
finally:
|
|
312
|
-
# Cleanup the SSH key files
|
|
313
|
-
# Only remove the files if they exist
|
|
314
|
-
try:
|
|
315
|
-
id_file.unlink()
|
|
316
|
-
pub_file.unlink()
|
|
317
|
-
except Exception as e:
|
|
318
|
-
warning(
|
|
319
|
-
f"Cleanup warning: Failed to delete SSH key files – {e}")
|
|
320
340
|
return True
|
|
321
341
|
|
|
322
342
|
# Commands
|
|
@@ -330,7 +350,8 @@ class Byows:
|
|
|
330
350
|
transient=True,
|
|
331
351
|
)
|
|
332
352
|
progress.start()
|
|
333
|
-
progress.add_task(
|
|
353
|
+
progress.add_task(
|
|
354
|
+
description='Setting up BYOWs port forward...', total=None)
|
|
334
355
|
try:
|
|
335
356
|
url = f"{self.base_url}/v1/snapser-api/byows/snapends/" + \
|
|
336
357
|
f"{self.snapend_id}/snaps/{self.byosnap_id}"
|
|
@@ -347,7 +368,6 @@ class Byows:
|
|
|
347
368
|
res.raise_for_status()
|
|
348
369
|
response_json = res.json()
|
|
349
370
|
|
|
350
|
-
|
|
351
371
|
if res.ok and 'workstationPort' in response_json and \
|
|
352
372
|
'workstationReversePort' in response_json and \
|
|
353
373
|
'snapendId' in response_json and \
|
|
@@ -364,6 +384,16 @@ class Byows:
|
|
|
364
384
|
|
|
365
385
|
progress.stop()
|
|
366
386
|
|
|
387
|
+
info('Setting up signal handling')
|
|
388
|
+
# Set up signal handling for cleanup
|
|
389
|
+
signal.signal(signal.SIGINT, functools.partial(
|
|
390
|
+
self._handle_signal))
|
|
391
|
+
signal.signal(signal.SIGTERM, functools.partial(
|
|
392
|
+
self._handle_signal))
|
|
393
|
+
if hasattr(signal, "SIGBREAK"):
|
|
394
|
+
signal.signal(signal.SIGBREAK,
|
|
395
|
+
functools.partial(self._handle_signal))
|
|
396
|
+
# Set up port forward
|
|
367
397
|
self._setup_port_forward(
|
|
368
398
|
response_json['proxyPrivateKey'],
|
|
369
399
|
response_json['proxyPublicKey'],
|
|
@@ -382,21 +412,56 @@ class Byows:
|
|
|
382
412
|
message='complete', progress=progress)
|
|
383
413
|
snapctl_error(
|
|
384
414
|
message='Unable to setup port forward.',
|
|
385
|
-
code=
|
|
415
|
+
code=SNAPCTL_BYOWS_ATTACH_ERROR, progress=progress)
|
|
386
416
|
except HTTPError as http_err:
|
|
387
417
|
snapctl_error(
|
|
388
418
|
message=Byows._format_portal_http_error(
|
|
389
419
|
"Unable to setup port forward", http_err, res),
|
|
390
|
-
code=
|
|
391
|
-
snapctl_error(
|
|
392
|
-
message=f"Server Error: Unable to setup port forward {http_err}",
|
|
393
|
-
code=SNAPCTL_BYOWS_GENERIC_ERROR, progress=progress)
|
|
420
|
+
code=SNAPCTL_BYOWS_ATTACH_ERROR, progress=progress)
|
|
394
421
|
except RequestException as e:
|
|
395
422
|
snapctl_error(
|
|
396
423
|
message=f"Exception: Unable to setup port forward {e}",
|
|
397
|
-
code=
|
|
424
|
+
code=SNAPCTL_BYOWS_ATTACH_ERROR, progress=progress)
|
|
425
|
+
finally:
|
|
426
|
+
progress.stop()
|
|
427
|
+
|
|
428
|
+
def reset(self) -> bool:
|
|
429
|
+
"""
|
|
430
|
+
BYOWs reset
|
|
431
|
+
"""
|
|
432
|
+
progress = Progress(
|
|
433
|
+
SpinnerColumn(),
|
|
434
|
+
TextColumn("[progress.description]{task.description}"),
|
|
435
|
+
transient=True,
|
|
436
|
+
)
|
|
437
|
+
progress.start()
|
|
438
|
+
progress.add_task(
|
|
439
|
+
description='Resetting BYOWS for the Snapend...', total=None)
|
|
440
|
+
try:
|
|
441
|
+
url = f"{self.base_url}/v1/snapser-api/byows/snapends/" + \
|
|
442
|
+
f"{self.snapend_id}"
|
|
443
|
+
res = requests.delete(
|
|
444
|
+
url,
|
|
445
|
+
headers={'api-key': self.api_key},
|
|
446
|
+
timeout=SERVER_CALL_TIMEOUT,
|
|
447
|
+
json={
|
|
448
|
+
"snapend_id": self.snapend_id,
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
res.raise_for_status()
|
|
452
|
+
if res.ok:
|
|
453
|
+
return snapctl_success(
|
|
454
|
+
message='Reset complete', progress=progress)
|
|
455
|
+
snapctl_error(
|
|
456
|
+
message='Unable to reset BYOWS.',
|
|
457
|
+
code=SNAPCTL_BYOWS_RESET_ERROR, progress=progress)
|
|
458
|
+
except HTTPError as http_err:
|
|
459
|
+
snapctl_error(
|
|
460
|
+
message=f"Server Error: Unable to reset BYOWS {http_err}",
|
|
461
|
+
code=SNAPCTL_BYOWS_RESET_ERROR, progress=progress)
|
|
462
|
+
except RequestException as e:
|
|
463
|
+
snapctl_error(
|
|
464
|
+
message=f"Exception: Unable to reset BYOWS {e}",
|
|
465
|
+
code=SNAPCTL_BYOWS_RESET_ERROR, progress=progress)
|
|
398
466
|
finally:
|
|
399
467
|
progress.stop()
|
|
400
|
-
snapctl_error(
|
|
401
|
-
message='Failed to setup port forward.',
|
|
402
|
-
code=SNAPCTL_BYOWS_GENERIC_ERROR, progress=progress)
|
|
@@ -3,7 +3,7 @@ Constants used by snapctl
|
|
|
3
3
|
"""
|
|
4
4
|
COMPANY_NAME = 'Snapser'
|
|
5
5
|
VERSION_PREFIX = 'beta-'
|
|
6
|
-
VERSION = '0.49.
|
|
6
|
+
VERSION = '0.49.4'
|
|
7
7
|
CONFIG_FILE_MAC = '~/.snapser/config'
|
|
8
8
|
CONFIG_FILE_WIN = '%homepath%\\.snapser\\config'
|
|
9
9
|
|
|
@@ -111,3 +111,5 @@ SNAPCTL_GENERATE_CREDENTIALS_ERROR = 81
|
|
|
111
111
|
|
|
112
112
|
# BYOWs Errors - 95 - 99
|
|
113
113
|
SNAPCTL_BYOWS_GENERIC_ERROR = 95
|
|
114
|
+
SNAPCTL_BYOWS_ATTACH_ERROR = 96
|
|
115
|
+
SNAPCTL_BYOWS_RESET_ERROR = 97
|
|
@@ -110,6 +110,7 @@ def get_base_url(api_key: Union[str, None]) -> str:
|
|
|
110
110
|
return END_POINTS['PLAYTEST']
|
|
111
111
|
return END_POINTS['PROD']
|
|
112
112
|
|
|
113
|
+
|
|
113
114
|
def get_base_snapend_url(api_key: Union[str, None]) -> str:
|
|
114
115
|
"""
|
|
115
116
|
Returns the base url for snapend based on the api_key
|
|
@@ -124,6 +125,7 @@ def get_base_snapend_url(api_key: Union[str, None]) -> str:
|
|
|
124
125
|
return GATEWAY_END_POINTS['SANDBOX']
|
|
125
126
|
return GATEWAY_END_POINTS['LIVE']
|
|
126
127
|
|
|
128
|
+
|
|
127
129
|
def validate_command_context(
|
|
128
130
|
ctx: typer.Context,
|
|
129
131
|
):
|
|
@@ -692,7 +694,7 @@ def byows(
|
|
|
692
694
|
# attach
|
|
693
695
|
snapend_id: str = typer.Option(
|
|
694
696
|
None, "--snapend-id",
|
|
695
|
-
help=("(req: attach) Your Snapend Id")
|
|
697
|
+
help=("(req: attach, reset) Your Snapend Id")
|
|
696
698
|
),
|
|
697
699
|
byosnap_id: str = typer.Option(
|
|
698
700
|
None, "--byosnap-id",
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|