snapctl 0.39.2__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.

@@ -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, SNAPCTL_SUCCESS, SNAPCTL_SNAPEND_CLONE_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, SERVER_SDK_TYPES, PROTOS_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
- 'client-sdk', 'server-sdk', 'protos', 'admin-settings', 'snapend-manifest'
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], snapend_id: 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: str, platform_type: str, protos_category: str, auth_type: str, snaps: Union[str, None],
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], byogs: Union[str, None], blocking: bool = False
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 == 'client-sdk':
105
- return CLIENT_SDK_TYPES
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 ['client-sdk', 'server-sdk']:
209
+ if self.category in ['sdk']:
202
210
  url += "&subtype=" + \
203
211
  f"{self.download_types[self.platform_type]['subtype']}"
204
- url_auth_type: str = 'user'
205
- if self.category == 'server-sdk' and self.auth_type == 'app':
206
- url_auth_type = 'app'
207
- url += f"&auth_type={url_auth_type}"
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.auth_type}.zip"
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("Missing API Key.", SNAPCTL_INPUT_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("Missing required parameter: game_id",
263
- SNAPCTL_INPUT_ERROR)
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("Missing required parameter: game_id",
267
- SNAPCTL_INPUT_ERROR)
281
+ snapctl_error(
282
+ message="Missing required parameter: game_id",
283
+ code=SNAPCTL_INPUT_ERROR)
268
284
  if not self.name:
269
- snapctl_error("Missing required parameter: name",
270
- SNAPCTL_INPUT_ERROR)
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("Invalid Download type.", SNAPCTL_INPUT_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 == 'server-sdk' and self.auth_type not in Snapend.AUTH_TYPES:
326
- snapctl_error(
327
- "Invalid auth type. Valid auth types are " +
328
- f"{', '.join(Snapend.AUTH_TYPES)}.",
329
- SNAPCTL_INPUT_ERROR
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("Missing required parameter: out-path",
334
- SNAPCTL_INPUT_ERROR)
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", SNAPCTL_INPUT_ERROR)
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", SNAPCTL_INPUT_ERROR)
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", SNAPCTL_INPUT_ERROR)
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(response_json['clusters'], progress)
435
+ snapctl_success(
436
+ message=response_json['clusters'],
437
+ progress=progress)
382
438
  except RequestException:
383
- snapctl_error("Snapctl Exception. Unable to enumerate snapends.",
384
- SNAPCTL_SNAPEND_ENUMERATE_ERROR, progress)
385
- snapctl_error("Unable to enumerate snapends.",
386
- SNAPCTL_SNAPEND_ENUMERATE_ERROR, progress)
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
- snapctl_error('Unable to apply the manifest.',
457
- SNAPCTL_SNAPEND_CLONE_ERROR, progress)
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 not up yet.' +
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(f'Unable to promote the manifest. Reason: {res.text}',
585
- SNAPCTL_SNAPEND_PROMOTE_ERROR, progress)
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
- snapctl_error("Unable to promote the snapend.",
592
- SNAPCTL_SNAPEND_PROMOTE_ERROR, progress)
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
- snapctl_error(f"Unable to download {self.category}",
619
- SNAPCTL_SNAPEND_DOWNLOAD_ERROR, progress)
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(f"Unable to update the snapend. Reason: {res.text}",
670
- SNAPCTL_SNAPEND_UPDATE_ERROR, progress)
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
- snapctl_error("Unable to update the snapend.",
677
- SNAPCTL_SNAPEND_UPDATE_ERROR, progress)
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("Unable to get the snapend state.",
699
- SNAPCTL_SNAPEND_STATE_ERROR, progress)
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
- snapctl_error("Unable to get the snapend state.",
706
- SNAPCTL_SNAPEND_STATE_ERROR, progress)
785
+ finally:
786
+ progress.stop()
787
+ snapctl_error(
788
+ message="Unable to get the snapend state.",
789
+ code=SNAPCTL_SNAPEND_STATE_ERROR, progress=progress)