snapctl 0.39.3__py3-none-any.whl → 0.41.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.
Potentially problematic release.
This version of snapctl might be problematic. Click here for more details.
- snapctl/commands/byogs.py +135 -56
- snapctl/commands/byosnap.py +450 -225
- snapctl/commands/game.py +49 -25
- snapctl/commands/generate.py +48 -40
- snapctl/commands/snapend.py +225 -142
- snapctl/config/constants.py +16 -4
- snapctl/config/hashes.py +5 -3
- snapctl/main.py +106 -34
- snapctl/utils/helper.py +2 -4
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/METADATA +66 -15
- snapctl-0.41.0.dist-info/RECORD +23 -0
- snapctl-0.39.3.dist-info/RECORD +0 -23
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/LICENSE +0 -0
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/WHEEL +0 -0
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/entry_points.txt +0 -0
snapctl/commands/snapend.py
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Snapend CLI commands
|
|
3
3
|
"""
|
|
4
|
-
from typing import Union
|
|
4
|
+
from typing import Dict, Union
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
7
|
import json
|
|
8
8
|
import time
|
|
9
9
|
import requests
|
|
10
|
-
from typing import Dict
|
|
11
10
|
from requests.exceptions import RequestException
|
|
12
11
|
|
|
13
12
|
import typer
|
|
14
13
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
15
14
|
from snapctl.config.constants import SERVER_CALL_TIMEOUT, SNAPCTL_INPUT_ERROR, \
|
|
16
15
|
SNAPCTL_SNAPEND_ENUMERATE_ERROR, SNAPCTL_SNAPEND_CLONE_SERVER_ERROR, \
|
|
17
|
-
SNAPCTL_SNAPEND_CLONE_TIMEOUT_ERROR,
|
|
16
|
+
SNAPCTL_SNAPEND_CLONE_TIMEOUT_ERROR, SNAPCTL_SNAPEND_CLONE_ERROR, \
|
|
18
17
|
SNAPCTL_SNAPEND_APPLY_SERVER_ERROR, SNAPCTL_SNAPEND_APPLY_TIMEOUT_ERROR, \
|
|
19
18
|
SNAPCTL_SNAPEND_APPLY_ERROR, SNAPCTL_SNAPEND_PROMOTE_SERVER_ERROR, \
|
|
20
19
|
SNAPCTL_SNAPEND_PROMOTE_TIMEOUT_ERROR, SNAPCTL_SNAPEND_PROMOTE_ERROR, \
|
|
21
20
|
SNAPCTL_SNAPEND_DOWNLOAD_ERROR, SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR, \
|
|
22
21
|
SNAPCTL_SNAPEND_UPDATE_ERROR, SNAPCTL_SNAPEND_STATE_ERROR
|
|
23
|
-
from snapctl.config.hashes import CLIENT_SDK_TYPES,
|
|
24
|
-
SNAPEND_MANIFEST_TYPES
|
|
22
|
+
from snapctl.config.hashes import CLIENT_SDK_TYPES, PROTOS_TYPES, \
|
|
23
|
+
SNAPEND_MANIFEST_TYPES, SDK_TYPES
|
|
25
24
|
from snapctl.utils.echo import error, success, info
|
|
26
25
|
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
27
26
|
|
|
@@ -35,30 +34,40 @@ class Snapend:
|
|
|
35
34
|
'download', 'update', 'state'
|
|
36
35
|
]
|
|
37
36
|
DOWNLOAD_CATEGORY = [
|
|
38
|
-
'
|
|
37
|
+
'sdk', 'protos',
|
|
38
|
+
'admin-settings', 'snapend-manifest'
|
|
39
39
|
]
|
|
40
40
|
DOWNLOAD_TYPE_NOT_REQUIRED = ['admin-settings']
|
|
41
41
|
PROTOS_CATEGORY = ['messages', 'services']
|
|
42
|
+
ACCESS_TYPES = ['external', 'internal']
|
|
42
43
|
AUTH_TYPES = ['user', 'app']
|
|
43
44
|
ENV_TYPES = ['DEVELOPMENT', 'STAGING']
|
|
44
45
|
BLOCKING_CALL_SLEEP = 5
|
|
45
46
|
MAX_BLOCKING_RETRIES = 120
|
|
46
47
|
|
|
47
48
|
def __init__(
|
|
48
|
-
self, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
49
|
+
self, *, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
50
|
+
snapend_id: Union[str, None] = None,
|
|
49
51
|
# Enumerate, Clone
|
|
50
|
-
game_id: Union[str, None],
|
|
52
|
+
game_id: Union[str, None] = None,
|
|
51
53
|
# Clone
|
|
52
|
-
name: Union[str, None],
|
|
53
|
-
env: Union[str, None],
|
|
54
|
+
name: Union[str, None] = None,
|
|
55
|
+
env: Union[str, None] = None,
|
|
54
56
|
# Clone, Apply, Promote
|
|
55
|
-
manifest_path: Union[str, None],
|
|
57
|
+
manifest_path: Union[str, None] = None,
|
|
56
58
|
# Download
|
|
57
|
-
category:
|
|
59
|
+
category: Union[str, None] = None,
|
|
60
|
+
sdk_access_type: Union[str, None] = 'external',
|
|
61
|
+
sdk_auth_type: Union[str, None] = 'user',
|
|
62
|
+
platform_type: Union[str, None] = None,
|
|
63
|
+
protos_category: Union[str, None] = None,
|
|
64
|
+
snaps: Union[str, None] = None,
|
|
58
65
|
# Clone, Apply, Promote, Download
|
|
59
|
-
out_path: Union[str, None],
|
|
66
|
+
out_path: Union[str, None] = None,
|
|
60
67
|
# Update
|
|
61
|
-
byosnaps: Union[str, None]
|
|
68
|
+
byosnaps: Union[str, None] = None,
|
|
69
|
+
byogs: Union[str, None] = None,
|
|
70
|
+
blocking: bool = False
|
|
62
71
|
) -> None:
|
|
63
72
|
self.subcommand: str = subcommand
|
|
64
73
|
self.base_url: str = base_url
|
|
@@ -72,11 +81,12 @@ class Snapend:
|
|
|
72
81
|
manifest_path
|
|
73
82
|
)
|
|
74
83
|
self.category: str = category
|
|
84
|
+
self.sdk_access_type: str = sdk_access_type
|
|
85
|
+
self.sdk_auth_type: str = sdk_auth_type
|
|
75
86
|
self.download_types: Union[
|
|
76
87
|
Dict[str, Dict[str, str]], None
|
|
77
88
|
] = Snapend._make_download_type(category)
|
|
78
89
|
self.protos_category: str = protos_category
|
|
79
|
-
self.auth_type: str = auth_type
|
|
80
90
|
self.platform_type: str = platform_type
|
|
81
91
|
self.out_path: Union[str, None] = out_path
|
|
82
92
|
self.snaps: Union[str, None] = snaps
|
|
@@ -101,10 +111,8 @@ class Snapend:
|
|
|
101
111
|
|
|
102
112
|
@staticmethod
|
|
103
113
|
def _make_download_type(category: str):
|
|
104
|
-
if category == '
|
|
105
|
-
return
|
|
106
|
-
if category == 'server-sdk':
|
|
107
|
-
return SERVER_SDK_TYPES
|
|
114
|
+
if category == 'sdk':
|
|
115
|
+
return SDK_TYPES
|
|
108
116
|
if category == 'protos':
|
|
109
117
|
return PROTOS_TYPES
|
|
110
118
|
if category == 'snapend-manifest':
|
|
@@ -198,13 +206,15 @@ class Snapend:
|
|
|
198
206
|
if self.category == 'protos':
|
|
199
207
|
url += f"&subtype={self.protos_category}"
|
|
200
208
|
# If client or server SDK, add sub type and auth type
|
|
201
|
-
if self.category in ['
|
|
209
|
+
if self.category in ['sdk']:
|
|
202
210
|
url += "&subtype=" + \
|
|
203
211
|
f"{self.download_types[self.platform_type]['subtype']}"
|
|
204
|
-
|
|
205
|
-
if self.
|
|
206
|
-
url_auth_type = '
|
|
207
|
-
|
|
212
|
+
url += f"&access_type={self.sdk_access_type}"
|
|
213
|
+
if self.sdk_access_type == 'external':
|
|
214
|
+
url_auth_type: str = 'user'
|
|
215
|
+
if self.category == 'sdk' and self.sdk_auth_type == 'app':
|
|
216
|
+
url_auth_type = 'app'
|
|
217
|
+
url += f"&auth_type={url_auth_type}"
|
|
208
218
|
# Customize snaps
|
|
209
219
|
if self.snaps:
|
|
210
220
|
url += f"&snaps={self.snaps}"
|
|
@@ -222,7 +232,10 @@ class Snapend:
|
|
|
222
232
|
f"-{self.platform_type}-{self.protos_category}.zip"
|
|
223
233
|
else:
|
|
224
234
|
fn = f"snapser-{self.snapend_id}-{self.category}" + \
|
|
225
|
-
f"-{self.platform_type}-{self.
|
|
235
|
+
f"-{self.platform_type}-{self.sdk_access_type}"
|
|
236
|
+
if self.sdk_access_type == 'external':
|
|
237
|
+
fn += f"-{self.sdk_auth_type}"
|
|
238
|
+
fn += ".zip"
|
|
226
239
|
if self.out_path is not None:
|
|
227
240
|
file_save_path = os.path.join(self.out_path, fn)
|
|
228
241
|
else:
|
|
@@ -249,104 +262,144 @@ class Snapend:
|
|
|
249
262
|
"""
|
|
250
263
|
# Check API Key and Base URL
|
|
251
264
|
if not self.api_key or self.base_url == '':
|
|
252
|
-
snapctl_error(
|
|
265
|
+
snapctl_error(
|
|
266
|
+
message="Missing API Key.", code=SNAPCTL_INPUT_ERROR)
|
|
253
267
|
# Check subcommand
|
|
254
268
|
if not self.subcommand in Snapend.SUBCOMMANDS:
|
|
255
269
|
snapctl_error(
|
|
256
|
-
"Invalid command. Valid commands are " +
|
|
270
|
+
message="Invalid command. Valid commands are " +
|
|
257
271
|
f"{', '.join(Snapend.SUBCOMMANDS)}.",
|
|
258
|
-
SNAPCTL_INPUT_ERROR
|
|
272
|
+
code=SNAPCTL_INPUT_ERROR
|
|
259
273
|
)
|
|
260
274
|
if self.subcommand == 'enumerate':
|
|
261
275
|
if not self.game_id:
|
|
262
|
-
snapctl_error(
|
|
263
|
-
|
|
276
|
+
snapctl_error(
|
|
277
|
+
message="Missing required parameter: game_id",
|
|
278
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
264
279
|
elif self.subcommand == 'clone':
|
|
265
280
|
if not self.game_id:
|
|
266
|
-
snapctl_error(
|
|
267
|
-
|
|
281
|
+
snapctl_error(
|
|
282
|
+
message="Missing required parameter: game_id",
|
|
283
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
268
284
|
if not self.name:
|
|
269
|
-
snapctl_error(
|
|
270
|
-
|
|
285
|
+
snapctl_error(
|
|
286
|
+
message="Missing required parameter: name",
|
|
287
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
271
288
|
if self.env.upper() not in Snapend.ENV_TYPES:
|
|
272
289
|
snapctl_error(
|
|
273
|
-
"Invalid environment. Valid environments are " +
|
|
290
|
+
message="Invalid environment. Valid environments are " +
|
|
274
291
|
f"{', '.join(Snapend.ENV_TYPES)}.",
|
|
275
|
-
SNAPCTL_INPUT_ERROR
|
|
292
|
+
code=SNAPCTL_INPUT_ERROR
|
|
276
293
|
)
|
|
277
294
|
if not self.manifest_path:
|
|
278
295
|
snapctl_error(
|
|
279
|
-
"Missing required parameter: manifest_path", SNAPCTL_INPUT_ERROR)
|
|
296
|
+
message="Missing required parameter: manifest_path", code=SNAPCTL_INPUT_ERROR)
|
|
280
297
|
if not os.path.isfile(self.manifest_path):
|
|
281
298
|
snapctl_error(
|
|
282
|
-
f"Invalid path {self.manifest_path}. " +
|
|
299
|
+
message=f"Invalid path {self.manifest_path}. " +
|
|
283
300
|
"Please enter a valid path to the manifest file",
|
|
284
|
-
SNAPCTL_INPUT_ERROR
|
|
301
|
+
code=SNAPCTL_INPUT_ERROR
|
|
285
302
|
)
|
|
286
303
|
elif self.subcommand == 'apply':
|
|
287
304
|
if not self.manifest_path:
|
|
288
305
|
snapctl_error(
|
|
289
|
-
"Missing required parameter: manifest_path", SNAPCTL_INPUT_ERROR)
|
|
306
|
+
message="Missing required parameter: manifest_path", code=SNAPCTL_INPUT_ERROR)
|
|
290
307
|
raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
|
|
291
308
|
if not os.path.isfile(self.manifest_path):
|
|
292
309
|
snapctl_error(
|
|
293
|
-
f"Invalid path {self.manifest_path}. " +
|
|
310
|
+
message=f"Invalid path {self.manifest_path}. " +
|
|
294
311
|
"Please enter a valid path to the manifest file",
|
|
295
|
-
SNAPCTL_INPUT_ERROR
|
|
312
|
+
code=SNAPCTL_INPUT_ERROR
|
|
296
313
|
)
|
|
297
314
|
if not self.manifest_file_name:
|
|
298
315
|
snapctl_error(
|
|
299
|
-
"Invalid manifest file. Supported formats are .json, .yml, .yaml",
|
|
300
|
-
SNAPCTL_INPUT_ERROR)
|
|
316
|
+
message="Invalid manifest file. Supported formats are .json, .yml, .yaml",
|
|
317
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
301
318
|
elif self.subcommand == 'download':
|
|
302
319
|
if not self.snapend_id:
|
|
303
320
|
snapctl_error(
|
|
304
|
-
"Missing required parameter: snapend_id", SNAPCTL_INPUT_ERROR)
|
|
321
|
+
message="Missing required parameter: snapend_id", code=SNAPCTL_INPUT_ERROR)
|
|
305
322
|
if not self.category:
|
|
306
323
|
snapctl_error(
|
|
307
|
-
"Missing required parameter: category", SNAPCTL_INPUT_ERROR)
|
|
324
|
+
message="Missing required parameter: category", code=SNAPCTL_INPUT_ERROR)
|
|
308
325
|
if self.category not in Snapend.DOWNLOAD_CATEGORY:
|
|
309
326
|
snapctl_error(
|
|
310
|
-
"Invalid SDK category. Valid categories are " +
|
|
327
|
+
message="Invalid SDK category. Valid categories are " +
|
|
311
328
|
f"{', '.join(Snapend.DOWNLOAD_CATEGORY)}.",
|
|
312
|
-
SNAPCTL_INPUT_ERROR
|
|
329
|
+
code=SNAPCTL_INPUT_ERROR
|
|
313
330
|
)
|
|
314
331
|
if self.category not in Snapend.DOWNLOAD_TYPE_NOT_REQUIRED and \
|
|
315
332
|
(self.download_types is None or self.platform_type not in self.download_types):
|
|
316
|
-
snapctl_error(
|
|
333
|
+
snapctl_error(
|
|
334
|
+
message="Invalid Download type.", code=SNAPCTL_INPUT_ERROR)
|
|
317
335
|
# Check the Protos category
|
|
318
336
|
if self.category == 'protos' and self.protos_category not in Snapend.PROTOS_CATEGORY:
|
|
319
337
|
snapctl_error(
|
|
320
|
-
"Invalid Protos category. Valid categories are " +
|
|
338
|
+
message="Invalid Protos category. Valid categories are " +
|
|
321
339
|
f"{', '.join(Snapend.PROTOS_CATEGORY)}.",
|
|
322
|
-
SNAPCTL_INPUT_ERROR
|
|
340
|
+
code=SNAPCTL_INPUT_ERROR
|
|
323
341
|
)
|
|
324
342
|
# Check the auth type
|
|
325
|
-
if self.category == '
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
343
|
+
if self.category == 'sdk':
|
|
344
|
+
if not self.sdk_access_type:
|
|
345
|
+
snapctl_error(
|
|
346
|
+
message="Missing required parameter: sdk-access-type",
|
|
347
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
348
|
+
if self.sdk_access_type not in Snapend.ACCESS_TYPES:
|
|
349
|
+
snapctl_error(
|
|
350
|
+
message="Invalid access type. Valid access types are " +
|
|
351
|
+
f"{', '.join(Snapend.ACCESS_TYPES)}.",
|
|
352
|
+
code=SNAPCTL_INPUT_ERROR
|
|
353
|
+
)
|
|
354
|
+
if self.sdk_access_type == 'external':
|
|
355
|
+
if not self.sdk_auth_type:
|
|
356
|
+
snapctl_error(
|
|
357
|
+
message="Missing required parameter: sdk-auth-type",
|
|
358
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
359
|
+
if self.sdk_auth_type not in Snapend.AUTH_TYPES:
|
|
360
|
+
snapctl_error(
|
|
361
|
+
message="Invalid auth type. Valid auth types are " +
|
|
362
|
+
f"{', '.join(Snapend.AUTH_TYPES)}.",
|
|
363
|
+
code=SNAPCTL_INPUT_ERROR
|
|
364
|
+
)
|
|
365
|
+
# Special cases for client SDKs
|
|
366
|
+
if self.platform_type in CLIENT_SDK_TYPES:
|
|
367
|
+
if self.sdk_access_type == 'external' and self.sdk_auth_type == 'app':
|
|
368
|
+
snapctl_error(
|
|
369
|
+
message="Invalid combination of access and auth type. " +
|
|
370
|
+
", ".join(CLIENT_SDK_TYPES.keys()) +
|
|
371
|
+
" SDKs are only available for sdk-access-type=external sdk-access-type=user",
|
|
372
|
+
code=SNAPCTL_INPUT_ERROR
|
|
373
|
+
)
|
|
374
|
+
if self.sdk_access_type == 'internal':
|
|
375
|
+
snapctl_error(
|
|
376
|
+
message="Internal access type is not supported for " +
|
|
377
|
+
", ".join(CLIENT_SDK_TYPES.keys()) + " SDKs.",
|
|
378
|
+
code=SNAPCTL_INPUT_ERROR
|
|
379
|
+
)
|
|
380
|
+
|
|
331
381
|
# Check file path
|
|
332
382
|
if not self.out_path:
|
|
333
|
-
snapctl_error(
|
|
334
|
-
|
|
383
|
+
snapctl_error(
|
|
384
|
+
message="Missing required parameter: out-path",
|
|
385
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
335
386
|
if self.out_path and not os.path.isdir(f"{self.out_path}"):
|
|
336
387
|
snapctl_error(
|
|
337
|
-
f"Invalid path {self.out_path}. " +
|
|
388
|
+
message=f"Invalid path {self.out_path}. " +
|
|
338
389
|
"Please enter a valid path to save your output file",
|
|
339
|
-
SNAPCTL_INPUT_ERROR
|
|
390
|
+
code=SNAPCTL_INPUT_ERROR
|
|
340
391
|
)
|
|
341
392
|
elif self.subcommand == 'promote':
|
|
342
393
|
if not self.snapend_id:
|
|
343
394
|
snapctl_error(
|
|
344
|
-
"Missing required parameter: snapend_id",
|
|
395
|
+
message="Missing required parameter: snapend_id",
|
|
396
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
345
397
|
# Check update commands
|
|
346
398
|
elif self.subcommand == 'update':
|
|
347
399
|
if not self.snapend_id:
|
|
348
400
|
snapctl_error(
|
|
349
|
-
"Missing required parameter: snapend_id",
|
|
401
|
+
message="Missing required parameter: snapend_id",
|
|
402
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
350
403
|
byosnap_present = True
|
|
351
404
|
if self.byosnap_list is None or len(self.byosnap_list) == 0:
|
|
352
405
|
byosnap_present = False
|
|
@@ -355,7 +408,8 @@ class Snapend:
|
|
|
355
408
|
byogs_present = False
|
|
356
409
|
if not byosnap_present and not byogs_present:
|
|
357
410
|
snapctl_error(
|
|
358
|
-
"The update command needs one of byosnaps or byogs",
|
|
411
|
+
message="The update command needs one of byosnaps or byogs",
|
|
412
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
359
413
|
|
|
360
414
|
## Subcommands ##
|
|
361
415
|
def enumerate(self) -> None:
|
|
@@ -378,12 +432,18 @@ class Snapend:
|
|
|
378
432
|
)
|
|
379
433
|
response_json = res.json()
|
|
380
434
|
if res.ok and 'clusters' in response_json:
|
|
381
|
-
snapctl_success(
|
|
435
|
+
snapctl_success(
|
|
436
|
+
message=response_json['clusters'],
|
|
437
|
+
progress=progress)
|
|
382
438
|
except RequestException:
|
|
383
|
-
snapctl_error(
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
439
|
+
snapctl_error(
|
|
440
|
+
message="Snapctl Exception. Unable to enumerate snapends.",
|
|
441
|
+
code=SNAPCTL_SNAPEND_ENUMERATE_ERROR, progress=progress)
|
|
442
|
+
finally:
|
|
443
|
+
progress.stop()
|
|
444
|
+
snapctl_error(
|
|
445
|
+
message="Unable to enumerate snapends.",
|
|
446
|
+
code=SNAPCTL_SNAPEND_ENUMERATE_ERROR, progress=progress)
|
|
387
447
|
|
|
388
448
|
def clone(self) -> None:
|
|
389
449
|
"""
|
|
@@ -416,10 +476,10 @@ class Snapend:
|
|
|
416
476
|
response = res.json()
|
|
417
477
|
if 'cluster' not in response or 'id' not in response['cluster']:
|
|
418
478
|
snapctl_error(
|
|
419
|
-
'Server Error. Unable to get a Snapend ID. ' +
|
|
479
|
+
message='Server Error. Unable to get a Snapend ID. ' +
|
|
420
480
|
'Please try again in sometime.',
|
|
421
|
-
SNAPCTL_SNAPEND_CLONE_SERVER_ERROR,
|
|
422
|
-
progress
|
|
481
|
+
code=SNAPCTL_SNAPEND_CLONE_SERVER_ERROR,
|
|
482
|
+
progress=progress
|
|
423
483
|
)
|
|
424
484
|
self._assign_snapend_id(response['cluster']['id'])
|
|
425
485
|
info(
|
|
@@ -433,28 +493,31 @@ class Snapend:
|
|
|
433
493
|
# self.manifest_file_name.split('.')[-1])
|
|
434
494
|
# self._execute_download()
|
|
435
495
|
snapctl_success(
|
|
436
|
-
'Snapend clone successful. Do not forget to download the latest manifest.',
|
|
437
|
-
progress)
|
|
496
|
+
message='Snapend clone successful. Do not forget to download the latest manifest.',
|
|
497
|
+
progress=progress)
|
|
438
498
|
snapctl_error(
|
|
439
|
-
'Snapend clone has been initiated but the Snapend is not up yet.' +
|
|
499
|
+
message='Snapend clone has been initiated but the Snapend is not up yet.' +
|
|
440
500
|
'Please try checking the status of the Snapend in some time',
|
|
441
|
-
SNAPCTL_SNAPEND_CLONE_TIMEOUT_ERROR,
|
|
442
|
-
progress
|
|
501
|
+
code=SNAPCTL_SNAPEND_CLONE_TIMEOUT_ERROR,
|
|
502
|
+
progress=progress
|
|
443
503
|
)
|
|
444
504
|
snapctl_success(
|
|
445
|
-
"Snapend clone has been initiated. " +
|
|
505
|
+
message="Snapend clone has been initiated. " +
|
|
446
506
|
"You can check the status using " +
|
|
447
507
|
"`snapctl snapend state --snapend-id" +
|
|
448
508
|
f"{response['cluster']['id']}`",
|
|
449
|
-
progress
|
|
509
|
+
progress=progress
|
|
450
510
|
)
|
|
451
511
|
except RequestException as e:
|
|
452
512
|
snapctl_error(
|
|
453
|
-
f"Unable to apply the manifest snapend. {e}",
|
|
454
|
-
SNAPCTL_SNAPEND_CLONE_ERROR, progress
|
|
513
|
+
message=f"Unable to apply the manifest snapend. {e}",
|
|
514
|
+
code=SNAPCTL_SNAPEND_CLONE_ERROR, progress=progress
|
|
455
515
|
)
|
|
456
|
-
|
|
457
|
-
|
|
516
|
+
finally:
|
|
517
|
+
progress.stop()
|
|
518
|
+
snapctl_error(
|
|
519
|
+
message='Unable to apply the manifest.',
|
|
520
|
+
code=SNAPCTL_SNAPEND_CLONE_ERROR, progress=progress)
|
|
458
521
|
|
|
459
522
|
def apply(self) -> None:
|
|
460
523
|
"""
|
|
@@ -484,10 +547,10 @@ class Snapend:
|
|
|
484
547
|
response = res.json()
|
|
485
548
|
if 'cluster' not in response or 'id' not in response['cluster']:
|
|
486
549
|
snapctl_error(
|
|
487
|
-
'Server Error. Unable to get a Snapend ID. '
|
|
550
|
+
message='Server Error. Unable to get a Snapend ID. '
|
|
488
551
|
'Please try again in sometime.',
|
|
489
|
-
SNAPCTL_SNAPEND_APPLY_SERVER_ERROR,
|
|
490
|
-
progress
|
|
552
|
+
code=SNAPCTL_SNAPEND_APPLY_SERVER_ERROR,
|
|
553
|
+
progress=progress
|
|
491
554
|
)
|
|
492
555
|
self._assign_snapend_id(response['cluster']['id'])
|
|
493
556
|
if self.blocking:
|
|
@@ -499,28 +562,30 @@ class Snapend:
|
|
|
499
562
|
# self.manifest_file_name.split('.')[-1])
|
|
500
563
|
# self._execute_download()
|
|
501
564
|
snapctl_success(
|
|
502
|
-
'Snapend apply successful. Do not forget to download ' +
|
|
565
|
+
message='Snapend apply successful. Do not forget to download ' +
|
|
503
566
|
'the latest manifest.',
|
|
504
|
-
progress)
|
|
567
|
+
progress=progress)
|
|
505
568
|
snapctl_error(
|
|
506
|
-
'Snapend apply has been initiated but the Snapend is
|
|
507
|
-
'Please try checking the status of the Snapend in some time',
|
|
508
|
-
SNAPCTL_SNAPEND_APPLY_TIMEOUT_ERROR, progress
|
|
569
|
+
message='Snapend apply has been initiated but the Snapend is ' +
|
|
570
|
+
'not up yet. Please try checking the status of the Snapend in some time',
|
|
571
|
+
code=SNAPCTL_SNAPEND_APPLY_TIMEOUT_ERROR, progress=progress
|
|
509
572
|
)
|
|
510
573
|
snapctl_success(
|
|
511
|
-
"Snapend apply has been initiated. " +
|
|
574
|
+
message="Snapend apply has been initiated. " +
|
|
512
575
|
"You can check the status using " +
|
|
513
576
|
"`snapctl snapend state --snapend-id" +
|
|
514
577
|
f"{response['cluster']['id']}`",
|
|
515
|
-
progress
|
|
578
|
+
progress=progress
|
|
516
579
|
)
|
|
517
580
|
except RequestException as e:
|
|
518
581
|
snapctl_error(
|
|
519
|
-
f"Unable to apply the manifest snapend. {e}",
|
|
520
|
-
SNAPCTL_SNAPEND_APPLY_ERROR, progress
|
|
582
|
+
message=f"Unable to apply the manifest snapend. {e}",
|
|
583
|
+
code=SNAPCTL_SNAPEND_APPLY_ERROR, progress=progress
|
|
521
584
|
)
|
|
585
|
+
finally:
|
|
586
|
+
progress.stop()
|
|
522
587
|
snapctl_error(
|
|
523
|
-
'Unable to apply the manifest.', SNAPCTL_SNAPEND_APPLY_ERROR, progress)
|
|
588
|
+
message='Unable to apply the manifest.', code=SNAPCTL_SNAPEND_APPLY_ERROR, progress=progress)
|
|
524
589
|
|
|
525
590
|
def promote(self) -> None:
|
|
526
591
|
"""
|
|
@@ -549,10 +614,10 @@ class Snapend:
|
|
|
549
614
|
response = res.json()
|
|
550
615
|
if 'cluster' not in response or 'id' not in response['cluster']:
|
|
551
616
|
snapctl_error(
|
|
552
|
-
'Server Error. Unable to get a Snapend ID. '
|
|
617
|
+
message='Server Error. Unable to get a Snapend ID. '
|
|
553
618
|
'Please try again in sometime.',
|
|
554
|
-
SNAPCTL_SNAPEND_PROMOTE_SERVER_ERROR,
|
|
555
|
-
progress
|
|
619
|
+
code=SNAPCTL_SNAPEND_PROMOTE_SERVER_ERROR,
|
|
620
|
+
progress=progress
|
|
556
621
|
)
|
|
557
622
|
self._assign_snapend_id(response['cluster']['id'])
|
|
558
623
|
if self.blocking:
|
|
@@ -564,32 +629,37 @@ class Snapend:
|
|
|
564
629
|
# self._execute_download()
|
|
565
630
|
# Fetch the new manifest
|
|
566
631
|
snapctl_success(
|
|
567
|
-
'Snapend promote successful. Do not forget to ' +
|
|
632
|
+
message='Snapend promote successful. Do not forget to ' +
|
|
568
633
|
'download the latest manifest.',
|
|
569
|
-
progress
|
|
634
|
+
progress=progress
|
|
570
635
|
)
|
|
571
636
|
snapctl_error(
|
|
572
|
-
'Snapend apply has been initiated but the Snapend is not up yet.' +
|
|
637
|
+
message='Snapend apply has been initiated but the Snapend is not up yet.' +
|
|
573
638
|
'Please try checking the status of the Snapend in some time',
|
|
574
|
-
SNAPCTL_SNAPEND_PROMOTE_TIMEOUT_ERROR,
|
|
575
|
-
progress
|
|
639
|
+
code=SNAPCTL_SNAPEND_PROMOTE_TIMEOUT_ERROR,
|
|
640
|
+
progress=progress
|
|
576
641
|
)
|
|
577
642
|
snapctl_success(
|
|
578
|
-
"Snapend apply has been initiated. " +
|
|
643
|
+
message="Snapend apply has been initiated. " +
|
|
579
644
|
"You can check the status using " +
|
|
580
645
|
"`snapctl snapend state --snapend-id" +
|
|
581
646
|
f"{response['cluster']['id']}`",
|
|
582
|
-
progress
|
|
647
|
+
progress=progress
|
|
583
648
|
)
|
|
584
|
-
snapctl_error(
|
|
585
|
-
|
|
649
|
+
snapctl_error(
|
|
650
|
+
message=f'Unable to promote the manifest. Reason: {
|
|
651
|
+
res.text}',
|
|
652
|
+
code=SNAPCTL_SNAPEND_PROMOTE_ERROR, progress=progress)
|
|
586
653
|
except RequestException as e:
|
|
587
654
|
snapctl_error(
|
|
588
|
-
f"Unable to promote the snapend. {e}",
|
|
589
|
-
SNAPCTL_SNAPEND_PROMOTE_ERROR, progress
|
|
655
|
+
message=f"Unable to promote the snapend. {e}",
|
|
656
|
+
code=SNAPCTL_SNAPEND_PROMOTE_ERROR, progress=progress
|
|
590
657
|
)
|
|
591
|
-
|
|
592
|
-
|
|
658
|
+
finally:
|
|
659
|
+
progress.stop()
|
|
660
|
+
snapctl_error(
|
|
661
|
+
message="Unable to promote the snapend.",
|
|
662
|
+
code=SNAPCTL_SNAPEND_PROMOTE_ERROR, progress=progress)
|
|
593
663
|
|
|
594
664
|
def download(self) -> None:
|
|
595
665
|
"""
|
|
@@ -606,19 +676,22 @@ class Snapend:
|
|
|
606
676
|
try:
|
|
607
677
|
if self._execute_download():
|
|
608
678
|
snapctl_success(
|
|
609
|
-
"Snapend download successful. " +
|
|
679
|
+
message="Snapend download successful. " +
|
|
610
680
|
f"{self.category} saved at {self.out_path}",
|
|
611
|
-
progress
|
|
681
|
+
progress=progress
|
|
612
682
|
)
|
|
613
683
|
except RequestException as e:
|
|
614
684
|
snapctl_error(
|
|
615
|
-
f"Unable to download {self.category}. Reason: {e}",
|
|
616
|
-
SNAPCTL_SNAPEND_DOWNLOAD_ERROR, progress
|
|
685
|
+
message=f"Unable to download {self.category}. Reason: {e}",
|
|
686
|
+
code=SNAPCTL_SNAPEND_DOWNLOAD_ERROR, progress=progress
|
|
617
687
|
)
|
|
618
|
-
|
|
619
|
-
|
|
688
|
+
finally:
|
|
689
|
+
progress.stop()
|
|
690
|
+
snapctl_error(
|
|
691
|
+
message=f"Unable to download {self.category}",
|
|
692
|
+
code=SNAPCTL_SNAPEND_DOWNLOAD_ERROR, progress=progress)
|
|
620
693
|
|
|
621
|
-
def update(self) -> None:
|
|
694
|
+
def update(self, no_exit: bool = False) -> None:
|
|
622
695
|
"""
|
|
623
696
|
Update a Snapend
|
|
624
697
|
"""
|
|
@@ -649,32 +722,38 @@ class Snapend:
|
|
|
649
722
|
# self._setup_for_download(
|
|
650
723
|
# self.manifest_file_name.split('.')[-1])
|
|
651
724
|
# self._execute_download()
|
|
652
|
-
snapctl_success(
|
|
653
|
-
'Snapend update successful. Do not forget to ' +
|
|
725
|
+
return snapctl_success(
|
|
726
|
+
message='Snapend update successful. Do not forget to ' +
|
|
654
727
|
'download the latest manifest.',
|
|
655
|
-
progress
|
|
728
|
+
progress=progress,
|
|
729
|
+
no_exit=no_exit
|
|
656
730
|
)
|
|
657
731
|
snapctl_error(
|
|
658
|
-
'Snapend update has been initiated. ' +
|
|
732
|
+
message='Snapend update has been initiated. ' +
|
|
659
733
|
'You can check the status using `snapctl snapend state`',
|
|
660
|
-
SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR,
|
|
661
|
-
progress
|
|
734
|
+
code=SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR,
|
|
735
|
+
progress=progress
|
|
662
736
|
)
|
|
663
|
-
snapctl_success(
|
|
664
|
-
"Snapend update has been initiated. " +
|
|
737
|
+
return snapctl_success(
|
|
738
|
+
message="Snapend update has been initiated. " +
|
|
665
739
|
"You can check the status using " +
|
|
666
740
|
f"`snapctl snapend state --snapend-id {self.snapend_id}`",
|
|
667
|
-
progress
|
|
741
|
+
progress=progress,
|
|
742
|
+
no_exit=no_exit
|
|
668
743
|
)
|
|
669
|
-
snapctl_error(
|
|
670
|
-
|
|
744
|
+
snapctl_error(
|
|
745
|
+
message=f"Unable to update the snapend. Reason: {res.text}",
|
|
746
|
+
code=SNAPCTL_SNAPEND_UPDATE_ERROR, progress=progress)
|
|
671
747
|
except RequestException as e:
|
|
672
748
|
snapctl_error(
|
|
673
|
-
f"Unable to update the snapend {e}",
|
|
674
|
-
SNAPCTL_SNAPEND_UPDATE_ERROR, progress
|
|
749
|
+
message=f"Unable to update the snapend {e}",
|
|
750
|
+
code=SNAPCTL_SNAPEND_UPDATE_ERROR, progress=progress
|
|
675
751
|
)
|
|
676
|
-
|
|
677
|
-
|
|
752
|
+
finally:
|
|
753
|
+
progress.stop()
|
|
754
|
+
snapctl_error(
|
|
755
|
+
message="Unable to update the snapend.",
|
|
756
|
+
code=SNAPCTL_SNAPEND_UPDATE_ERROR, progress=progress)
|
|
678
757
|
|
|
679
758
|
def state(self) -> None:
|
|
680
759
|
"""
|
|
@@ -692,15 +771,19 @@ class Snapend:
|
|
|
692
771
|
current_state = self._get_snapend_state()
|
|
693
772
|
if current_state != 'INVALID':
|
|
694
773
|
snapctl_success(
|
|
695
|
-
'Snapend get state successful. Current snapend state is: ' +
|
|
774
|
+
message='Snapend get state successful. Current snapend state is: ' +
|
|
696
775
|
f'{current_state}',
|
|
697
|
-
progress)
|
|
698
|
-
snapctl_error(
|
|
699
|
-
|
|
776
|
+
progress=progress)
|
|
777
|
+
snapctl_error(
|
|
778
|
+
message="Unable to get the snapend state.",
|
|
779
|
+
code=SNAPCTL_SNAPEND_STATE_ERROR, progress=progress)
|
|
700
780
|
except RequestException as e:
|
|
701
781
|
snapctl_error(
|
|
702
|
-
f"Unable to get your snapend state {e}",
|
|
703
|
-
SNAPCTL_SNAPEND_STATE_ERROR, progress
|
|
782
|
+
message=f"Unable to get your snapend state {e}",
|
|
783
|
+
code=SNAPCTL_SNAPEND_STATE_ERROR, progress=progress
|
|
704
784
|
)
|
|
705
|
-
|
|
706
|
-
|
|
785
|
+
finally:
|
|
786
|
+
progress.stop()
|
|
787
|
+
snapctl_error(
|
|
788
|
+
message="Unable to get the snapend state.",
|
|
789
|
+
code=SNAPCTL_SNAPEND_STATE_ERROR, progress=progress)
|