snapctl 0.38.0__py3-none-any.whl → 0.38.1__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 +10 -10
- snapctl/commands/byosnap.py +41 -39
- snapctl/commands/game.py +7 -9
- snapctl/commands/generate.py +11 -11
- snapctl/commands/snapend.py +65 -50
- snapctl/config/constants.py +1 -1
- snapctl/config/hashes.py +12 -10
- snapctl/main.py +8 -8
- snapctl/utils/helper.py +11 -13
- {snapctl-0.38.0.dist-info → snapctl-0.38.1.dist-info}/METADATA +1 -1
- snapctl-0.38.1.dist-info/RECORD +23 -0
- snapctl-0.38.0.dist-info/RECORD +0 -23
- {snapctl-0.38.0.dist-info → snapctl-0.38.1.dist-info}/LICENSE +0 -0
- {snapctl-0.38.0.dist-info → snapctl-0.38.1.dist-info}/WHEEL +0 -0
- {snapctl-0.38.0.dist-info → snapctl-0.38.1.dist-info}/entry_points.txt +0 -0
snapctl/commands/byogs.py
CHANGED
|
@@ -7,7 +7,7 @@ import os
|
|
|
7
7
|
import subprocess
|
|
8
8
|
import platform as sys_platform
|
|
9
9
|
from sys import platform
|
|
10
|
-
from typing import Union
|
|
10
|
+
from typing import Union, List
|
|
11
11
|
|
|
12
12
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
13
13
|
from snapctl.config.constants import SNAPCTL_BYOGS_DEPENDENCY_MISSING, \
|
|
@@ -32,7 +32,7 @@ class ByoGs:
|
|
|
32
32
|
TAG_CHARACTER_LIMIT = 80
|
|
33
33
|
|
|
34
34
|
def __init__(
|
|
35
|
-
self, subcommand: str, base_url: str, api_key: str
|
|
35
|
+
self, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
36
36
|
input_tag: Union[str, None], path: Union[str, None], dockerfile: str,
|
|
37
37
|
skip_build: bool = False
|
|
38
38
|
) -> None:
|
|
@@ -46,7 +46,7 @@ class ByoGs:
|
|
|
46
46
|
self.token: Union[str, None] = get_composite_token(
|
|
47
47
|
base_url, api_key, 'byogs', {'service_id': ByoGs.SID}
|
|
48
48
|
)
|
|
49
|
-
self.token_parts: Union[
|
|
49
|
+
self.token_parts: Union[List, None] = ByoGs._get_token_values(
|
|
50
50
|
self.token) if self.token is not None else None
|
|
51
51
|
self.input_tag: Union[str, None] = input_tag
|
|
52
52
|
self.path: Union[str, None] = path
|
|
@@ -58,7 +58,7 @@ class ByoGs:
|
|
|
58
58
|
# Protected methods
|
|
59
59
|
|
|
60
60
|
@staticmethod
|
|
61
|
-
def _get_token_values(token: str) -> None
|
|
61
|
+
def _get_token_values(token: str) -> Union[None, List]:
|
|
62
62
|
"""
|
|
63
63
|
Get the token values
|
|
64
64
|
"""
|
|
@@ -124,7 +124,7 @@ class ByoGs:
|
|
|
124
124
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
125
125
|
else:
|
|
126
126
|
response = subprocess.run([
|
|
127
|
-
f'echo "{ecr_repo_token}" | docker login '
|
|
127
|
+
f'echo "{ecr_repo_token}" | docker login ' +
|
|
128
128
|
f'--username {ecr_repo_username} --password-stdin {ecr_repo_url}'
|
|
129
129
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
130
130
|
if not response.returncode:
|
|
@@ -169,8 +169,8 @@ class ByoGs:
|
|
|
169
169
|
else:
|
|
170
170
|
response = subprocess.run([
|
|
171
171
|
# f"docker build --no-cache -t {tag} {path}"
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
"docker build --platform " +
|
|
173
|
+
f"{build_platform} -t {self.input_tag} " +
|
|
174
174
|
f"-f {docker_file_path} {self.path}"
|
|
175
175
|
], shell=True, check=False)
|
|
176
176
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
@@ -257,8 +257,8 @@ class ByoGs:
|
|
|
257
257
|
# Check subcommand
|
|
258
258
|
if not self.subcommand in ByoGs.SUBCOMMANDS:
|
|
259
259
|
snapctl_error(
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
"Invalid command. Valid commands are " +
|
|
261
|
+
f"{', '.join(ByoGs.SUBCOMMANDS)}.",
|
|
262
262
|
SNAPCTL_INPUT_ERROR)
|
|
263
263
|
# Validation for subcommands
|
|
264
264
|
if self.token_parts is None:
|
|
@@ -270,7 +270,7 @@ class ByoGs:
|
|
|
270
270
|
SNAPCTL_INPUT_ERROR)
|
|
271
271
|
if len(self.input_tag.split()) > 1 or len(self.input_tag) > ByoGs.TAG_CHARACTER_LIMIT:
|
|
272
272
|
snapctl_error(
|
|
273
|
-
"Tag should be a single word with maximum of "
|
|
273
|
+
"Tag should be a single word with maximum of " +
|
|
274
274
|
f"{ByoGs.TAG_CHARACTER_LIMIT} characters",
|
|
275
275
|
SNAPCTL_INPUT_ERROR
|
|
276
276
|
)
|
snapctl/commands/byosnap.py
CHANGED
|
@@ -9,7 +9,7 @@ import re
|
|
|
9
9
|
import subprocess
|
|
10
10
|
import platform as sys_platform
|
|
11
11
|
from sys import platform
|
|
12
|
-
from typing import Union
|
|
12
|
+
from typing import Union, List
|
|
13
13
|
import requests
|
|
14
14
|
from requests.exceptions import RequestException
|
|
15
15
|
|
|
@@ -47,7 +47,7 @@ class ByoSnap:
|
|
|
47
47
|
MAX_MIN_REPLICAS = 4
|
|
48
48
|
|
|
49
49
|
def __init__(
|
|
50
|
-
self, subcommand: str, base_url: str, api_key: str
|
|
50
|
+
self, subcommand: str, base_url: str, api_key: Union[str, None], sid: str, name: str,
|
|
51
51
|
desc: str, platform_type: str, language: str, input_tag: Union[str, None],
|
|
52
52
|
path: Union[str, None], dockerfile: str, prefix: str, version: Union[str, None],
|
|
53
53
|
http_port: Union[int, None], byosnap_profile: Union[str, None],
|
|
@@ -86,7 +86,7 @@ class ByoSnap:
|
|
|
86
86
|
|
|
87
87
|
# Protected methods
|
|
88
88
|
@staticmethod
|
|
89
|
-
def _get_token_values(token: str) -> None
|
|
89
|
+
def _get_token_values(token: str) -> Union[None, List]:
|
|
90
90
|
"""
|
|
91
91
|
Method to break open the token
|
|
92
92
|
"""
|
|
@@ -157,7 +157,7 @@ class ByoSnap:
|
|
|
157
157
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
158
158
|
else:
|
|
159
159
|
response = subprocess.run([
|
|
160
|
-
f'echo "{ecr_repo_token}" | docker login '
|
|
160
|
+
f'echo "{ecr_repo_token}" | docker login ' +
|
|
161
161
|
f'--username {ecr_repo_username} --password-stdin {ecr_repo_url}'
|
|
162
162
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
163
163
|
if not response.returncode:
|
|
@@ -203,8 +203,8 @@ class ByoSnap:
|
|
|
203
203
|
else:
|
|
204
204
|
response = subprocess.run([
|
|
205
205
|
# f"docker build --no-cache -t {tag} {path}"
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
"docker build --platform " +
|
|
207
|
+
f"{build_platform} -t {self.input_tag} " +
|
|
208
208
|
f"-f {docker_file_path} {self.path}"
|
|
209
209
|
], shell=True, check=False)
|
|
210
210
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
@@ -292,8 +292,8 @@ class ByoSnap:
|
|
|
292
292
|
snapctl_error("Missing BYOSnap profile path", SNAPCTL_INPUT_ERROR)
|
|
293
293
|
if not os.path.isfile(self.byosnap_profile):
|
|
294
294
|
snapctl_error(
|
|
295
|
-
"Unable to find BYOSnap profile "
|
|
296
|
-
|
|
295
|
+
"Unable to find BYOSnap profile " +
|
|
296
|
+
f"JSON at path {self.byosnap_profile}",
|
|
297
297
|
SNAPCTL_INPUT_ERROR
|
|
298
298
|
)
|
|
299
299
|
profile_data = None
|
|
@@ -327,16 +327,14 @@ class ByoSnap:
|
|
|
327
327
|
)
|
|
328
328
|
if profile_data[profile]['cpu'] not in ByoSnap.VALID_CPU_MARKS:
|
|
329
329
|
snapctl_error(
|
|
330
|
-
'Invalid CPU value in BYOSnap profile. '
|
|
331
|
-
f'
|
|
332
|
-
", ".join(map(str, ByoSnap.VALID_CPU_MARKS))}',
|
|
330
|
+
'Invalid CPU value in BYOSnap profile. Valid values are' +
|
|
331
|
+
f'{", ".join(map(str, ByoSnap.VALID_CPU_MARKS))}',
|
|
333
332
|
SNAPCTL_INPUT_ERROR
|
|
334
333
|
)
|
|
335
334
|
if profile_data[profile]['memory'] not in ByoSnap.VALID_MEMORY_MARKS:
|
|
336
335
|
snapctl_error(
|
|
337
|
-
'Invalid Memory value in BYOSnap profile. '
|
|
338
|
-
f'
|
|
339
|
-
", ".join(map(str, ByoSnap.VALID_MEMORY_MARKS))}',
|
|
336
|
+
'Invalid Memory value in BYOSnap profile. Valid values are ' +
|
|
337
|
+
f'{", ".join(map(str, ByoSnap.VALID_MEMORY_MARKS))}',
|
|
340
338
|
SNAPCTL_INPUT_ERROR
|
|
341
339
|
)
|
|
342
340
|
if 'min_replicas' in profile_data[profile] and \
|
|
@@ -344,9 +342,9 @@ class ByoSnap:
|
|
|
344
342
|
int(profile_data[profile]['min_replicas']) < 0 or
|
|
345
343
|
int(profile_data[profile]['min_replicas']) > ByoSnap.MAX_MIN_REPLICAS):
|
|
346
344
|
snapctl_error(
|
|
347
|
-
'Invalid Min Replicas value in BYOSnap profile. '
|
|
348
|
-
|
|
349
|
-
|
|
345
|
+
'Invalid Min Replicas value in BYOSnap profile. ' +
|
|
346
|
+
'Minimum replicas should be between 0 and ' +
|
|
347
|
+
f'{ByoSnap.MAX_MIN_REPLICAS}',
|
|
350
348
|
SNAPCTL_INPUT_ERROR
|
|
351
349
|
)
|
|
352
350
|
|
|
@@ -363,22 +361,21 @@ class ByoSnap:
|
|
|
363
361
|
# Check subcommand
|
|
364
362
|
if not self.subcommand in ByoSnap.SUBCOMMANDS:
|
|
365
363
|
snapctl_error(
|
|
366
|
-
"Invalid command. Valid commands "
|
|
367
|
-
f"
|
|
364
|
+
"Invalid command. Valid commands are " +
|
|
365
|
+
f"{', '.join(ByoSnap.SUBCOMMANDS)}.",
|
|
368
366
|
SNAPCTL_INPUT_ERROR
|
|
369
367
|
)
|
|
370
368
|
# Validate the SID
|
|
371
369
|
if not self.sid.startswith(ByoSnap.ID_PREFIX):
|
|
372
370
|
snapctl_error(
|
|
373
|
-
|
|
374
|
-
|
|
371
|
+
"Invalid Snap ID. Valid Snap IDs start with " +
|
|
372
|
+
f"{ByoSnap.ID_PREFIX}.",
|
|
375
373
|
SNAPCTL_INPUT_ERROR
|
|
376
374
|
)
|
|
377
375
|
if len(self.sid) > ByoSnap.SID_CHARACTER_LIMIT:
|
|
378
376
|
snapctl_error(
|
|
379
|
-
"Invalid Snap ID. "
|
|
380
|
-
f"
|
|
381
|
-
ByoSnap.SID_CHARACTER_LIMIT} characters",
|
|
377
|
+
"Invalid Snap ID. Snap ID should be less than " +
|
|
378
|
+
f"{ByoSnap.SID_CHARACTER_LIMIT} characters",
|
|
382
379
|
SNAPCTL_INPUT_ERROR
|
|
383
380
|
)
|
|
384
381
|
# Validation for subcommands
|
|
@@ -389,13 +386,13 @@ class ByoSnap:
|
|
|
389
386
|
snapctl_error("Missing language", SNAPCTL_INPUT_ERROR)
|
|
390
387
|
if self.language not in ByoSnap.LANGUAGES:
|
|
391
388
|
snapctl_error(
|
|
392
|
-
"Invalid language. Valid languages are "
|
|
389
|
+
"Invalid language. Valid languages are " +
|
|
393
390
|
f"{', '.join(ByoSnap.LANGUAGES)}.",
|
|
394
391
|
SNAPCTL_INPUT_ERROR
|
|
395
392
|
)
|
|
396
393
|
if self.platform_type not in ByoSnap.PLATFORMS:
|
|
397
394
|
snapctl_error(
|
|
398
|
-
"Invalid platform. Valid platforms are "
|
|
395
|
+
"Invalid platform. Valid platforms are " +
|
|
399
396
|
f"{', '.join(ByoSnap.PLATFORMS)}.",
|
|
400
397
|
SNAPCTL_INPUT_ERROR
|
|
401
398
|
)
|
|
@@ -411,7 +408,7 @@ class ByoSnap:
|
|
|
411
408
|
if len(self.input_tag.split()) > 1 or \
|
|
412
409
|
len(self.input_tag) > ByoSnap.TAG_CHARACTER_LIMIT:
|
|
413
410
|
snapctl_error(
|
|
414
|
-
"Tag should be a single word with maximum of "
|
|
411
|
+
"Tag should be a single word with maximum of " +
|
|
415
412
|
f"{ByoSnap.TAG_CHARACTER_LIMIT} characters",
|
|
416
413
|
SNAPCTL_INPUT_ERROR
|
|
417
414
|
)
|
|
@@ -421,8 +418,8 @@ class ByoSnap:
|
|
|
421
418
|
# Check path
|
|
422
419
|
if not self.skip_build and not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
423
420
|
snapctl_error(
|
|
424
|
-
f"Unable to find
|
|
425
|
-
|
|
421
|
+
f"Unable to find " +
|
|
422
|
+
f"{self.dockerfile} at path {self.path}",
|
|
426
423
|
SNAPCTL_INPUT_ERROR)
|
|
427
424
|
# elif self.subcommand == 'push':
|
|
428
425
|
# if not self.input_tag:
|
|
@@ -439,7 +436,7 @@ class ByoSnap:
|
|
|
439
436
|
if len(self.input_tag.split()) > 1 or \
|
|
440
437
|
len(self.input_tag) > ByoSnap.TAG_CHARACTER_LIMIT:
|
|
441
438
|
snapctl_error(
|
|
442
|
-
"Tag should be a single word with maximum of "
|
|
439
|
+
"Tag should be a single word with maximum of " +
|
|
443
440
|
f"{ByoSnap.TAG_CHARACTER_LIMIT} characters",
|
|
444
441
|
SNAPCTL_INPUT_ERROR
|
|
445
442
|
)
|
|
@@ -473,8 +470,9 @@ class ByoSnap:
|
|
|
473
470
|
if self.readiness_delay is not None:
|
|
474
471
|
if self.readiness_delay < 0 or \
|
|
475
472
|
self.readiness_delay > ByoSnap.MAX_READINESS_TIMEOUT:
|
|
476
|
-
snapctl_error(
|
|
477
|
-
|
|
473
|
+
snapctl_error(
|
|
474
|
+
"Readiness delay should be between 0 " +
|
|
475
|
+
f"and {ByoSnap.MAX_READINESS_TIMEOUT}", SNAPCTL_INPUT_ERROR)
|
|
478
476
|
# Check byosnap_profile path
|
|
479
477
|
self._validate_byosnap_profile()
|
|
480
478
|
|
|
@@ -539,12 +537,14 @@ class ByoSnap:
|
|
|
539
537
|
info('Unable to upload your swagger.json')
|
|
540
538
|
except RequestException as e:
|
|
541
539
|
info(
|
|
542
|
-
|
|
543
|
-
|
|
540
|
+
'Exception: Unable to find swagger.json at ' +
|
|
541
|
+
f'{self.path} {e}'
|
|
544
542
|
)
|
|
545
543
|
else:
|
|
546
|
-
info(
|
|
547
|
-
|
|
544
|
+
info(
|
|
545
|
+
f'No swagger.json found at {self.path}' +
|
|
546
|
+
'. Skipping swagger.json upload'
|
|
547
|
+
)
|
|
548
548
|
|
|
549
549
|
# Push the README.md
|
|
550
550
|
if os.path.isfile(readme_file):
|
|
@@ -566,7 +566,9 @@ class ByoSnap:
|
|
|
566
566
|
info('Unable to upload your README.md')
|
|
567
567
|
except RequestException as e:
|
|
568
568
|
info(
|
|
569
|
-
|
|
569
|
+
'Exception: Unable to find README.md at ' +
|
|
570
|
+
f'{self.path} {str(e)}'
|
|
571
|
+
)
|
|
570
572
|
else:
|
|
571
573
|
info(
|
|
572
574
|
f'No README.md found at {self.path}. Skipping README.md upload')
|
|
@@ -606,8 +608,8 @@ class ByoSnap:
|
|
|
606
608
|
if "api_error_code" in response_json and "message" in response_json:
|
|
607
609
|
if response_json['api_error_code'] == HTTP_ERROR_SERVICE_VERSION_EXISTS:
|
|
608
610
|
snapctl_error(
|
|
609
|
-
f'BYOSnap {
|
|
610
|
-
|
|
611
|
+
f'BYOSnap {self.name} already exists. ' +
|
|
612
|
+
'Please use a different name',
|
|
611
613
|
SNAPCTL_BYOSNAP_CREATE_DUPLICATE_NAME_ERROR,
|
|
612
614
|
progress
|
|
613
615
|
)
|
snapctl/commands/game.py
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Snapend CLI commands
|
|
3
3
|
"""
|
|
4
|
+
from typing import Union, Dict
|
|
4
5
|
import requests
|
|
5
6
|
from requests.exceptions import RequestException
|
|
6
|
-
|
|
7
|
-
import typer
|
|
8
7
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
9
8
|
from snapctl.config.constants import SERVER_CALL_TIMEOUT, SNAPCTL_INPUT_ERROR, \
|
|
10
|
-
|
|
9
|
+
SNAPCTL_GAME_CREATE_ERROR, SNAPCTL_GAME_ENUMERATE_ERROR, \
|
|
11
10
|
HTTP_ERROR_DUPLICATE_GAME_NAME, SNAPCTL_GAME_CREATE_DUPLICATE_NAME_ERROR
|
|
12
|
-
from snapctl.utils.echo import error, success
|
|
13
11
|
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
14
12
|
|
|
15
13
|
|
|
@@ -20,12 +18,12 @@ class Game:
|
|
|
20
18
|
SUBCOMMANDS = ['create', 'enumerate']
|
|
21
19
|
|
|
22
20
|
def __init__(
|
|
23
|
-
self, subcommand: str, base_url: str, api_key: str
|
|
21
|
+
self, subcommand: str, base_url: str, api_key: Union[str, None], name: Union[str, None]
|
|
24
22
|
) -> None:
|
|
25
23
|
self.subcommand: str = subcommand
|
|
26
24
|
self.base_url: str = base_url
|
|
27
25
|
self.api_key: str = api_key
|
|
28
|
-
self.name: str
|
|
26
|
+
self.name: Union[str, None] = name
|
|
29
27
|
# Validate input
|
|
30
28
|
self.validate_input()
|
|
31
29
|
|
|
@@ -38,9 +36,9 @@ class Game:
|
|
|
38
36
|
snapctl_error("Missing API Key.", SNAPCTL_INPUT_ERROR)
|
|
39
37
|
# Check subcommand
|
|
40
38
|
if not self.subcommand in Game.SUBCOMMANDS:
|
|
41
|
-
snapctl_error(
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
snapctl_error("Invalid command. Valid commands are" +
|
|
40
|
+
f"{', '.join(Game.SUBCOMMANDS)}.",
|
|
41
|
+
SNAPCTL_INPUT_ERROR)
|
|
44
42
|
# Check sdk-download commands
|
|
45
43
|
if self.subcommand == 'create':
|
|
46
44
|
if self.name is None or self.name == '':
|
snapctl/commands/generate.py
CHANGED
|
@@ -5,7 +5,7 @@ import base64
|
|
|
5
5
|
from binascii import Error as BinasciiError
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
|
-
from typing import Union
|
|
8
|
+
from typing import Union, List
|
|
9
9
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
10
10
|
from snapctl.config.constants import SNAPCTL_INPUT_ERROR, \
|
|
11
11
|
SNAPCTL_GENERATE_GENERIC_ERROR, SNAPCTL_GENERATE_PROFILE_ERROR, \
|
|
@@ -28,21 +28,21 @@ class Generate:
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
def __init__(
|
|
31
|
-
self, subcommand: str, base_url: str, api_key: str
|
|
32
|
-
category: str
|
|
31
|
+
self, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
32
|
+
category: Union[str, None],
|
|
33
33
|
out_path: Union[str, None]
|
|
34
34
|
) -> None:
|
|
35
35
|
self.subcommand: str = subcommand
|
|
36
36
|
self.base_url: str = base_url
|
|
37
37
|
self.api_key: str = api_key
|
|
38
|
-
self.category: str
|
|
38
|
+
self.category: Union[str, None] = category
|
|
39
39
|
self.out_path: Union[str, None] = out_path
|
|
40
40
|
# Validate input
|
|
41
41
|
self.validate_input()
|
|
42
42
|
|
|
43
43
|
# Private methods
|
|
44
44
|
@staticmethod
|
|
45
|
-
def _get_token_values(token: str) -> None
|
|
45
|
+
def _get_token_values(token: str) -> Union[None, List]:
|
|
46
46
|
"""
|
|
47
47
|
Get the token values
|
|
48
48
|
"""
|
|
@@ -63,7 +63,7 @@ class Generate:
|
|
|
63
63
|
"""
|
|
64
64
|
if self.subcommand not in Generate.SUBCOMMANDS:
|
|
65
65
|
snapctl_error(
|
|
66
|
-
f"Invalid command {self.subcommand}. Valid command are "
|
|
66
|
+
f"Invalid command {self.subcommand}. Valid command are " +
|
|
67
67
|
f"{Generate.SUBCOMMANDS}",
|
|
68
68
|
SNAPCTL_INPUT_ERROR
|
|
69
69
|
)
|
|
@@ -71,7 +71,7 @@ class Generate:
|
|
|
71
71
|
if self.subcommand == 'profile':
|
|
72
72
|
if self.category not in Generate.CATEGORIES['profile']:
|
|
73
73
|
snapctl_error(
|
|
74
|
-
f"Invalid category {self.category}. Valid category are "
|
|
74
|
+
f"Invalid category {self.category}. Valid category are " +
|
|
75
75
|
f"{Generate.CATEGORIES['profile']}",
|
|
76
76
|
SNAPCTL_INPUT_ERROR
|
|
77
77
|
)
|
|
@@ -83,7 +83,7 @@ class Generate:
|
|
|
83
83
|
elif self.subcommand == 'credentials':
|
|
84
84
|
if self.category not in Generate.CATEGORIES['credentials']:
|
|
85
85
|
snapctl_error(
|
|
86
|
-
f"Invalid category {self.category}. Valid category are "
|
|
86
|
+
f"Invalid category {self.category}. Valid category are " +
|
|
87
87
|
f"{Generate.CATEGORIES['credentials']}",
|
|
88
88
|
SNAPCTL_INPUT_ERROR
|
|
89
89
|
)
|
|
@@ -95,7 +95,7 @@ class Generate:
|
|
|
95
95
|
# Now confirm that out-path is valid
|
|
96
96
|
if self.out_path and not os.path.isdir(self.out_path):
|
|
97
97
|
snapctl_error(
|
|
98
|
-
f"Invalid path {self.out_path}. Wont be able to "
|
|
98
|
+
f"Invalid path {self.out_path}. Wont be able to " +
|
|
99
99
|
"store the output file",
|
|
100
100
|
SNAPCTL_INPUT_ERROR
|
|
101
101
|
)
|
|
@@ -125,7 +125,7 @@ class Generate:
|
|
|
125
125
|
file_written = True
|
|
126
126
|
if file_written:
|
|
127
127
|
snapctl_success(
|
|
128
|
-
"BYOSNAP Profile generation successful. "
|
|
128
|
+
"BYOSNAP Profile generation successful. " +
|
|
129
129
|
f"{Generate.BYOSNAP_PROFILE_FN} saved at {file_save_path}",
|
|
130
130
|
progress
|
|
131
131
|
)
|
|
@@ -191,7 +191,7 @@ class Generate:
|
|
|
191
191
|
file_written = True
|
|
192
192
|
if file_written:
|
|
193
193
|
snapctl_success(
|
|
194
|
-
"ECR Token generation successful. "
|
|
194
|
+
"ECR Token generation successful. " +
|
|
195
195
|
f"{Generate.ECR_TOKEN_FN} saved at {file_save_path}",
|
|
196
196
|
progress
|
|
197
197
|
)
|
snapctl/commands/snapend.py
CHANGED
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import json
|
|
8
8
|
import time
|
|
9
9
|
import requests
|
|
10
|
+
from typing import Dict
|
|
10
11
|
from requests.exceptions import RequestException
|
|
11
12
|
|
|
12
13
|
import typer
|
|
@@ -44,44 +45,44 @@ class Snapend:
|
|
|
44
45
|
MAX_BLOCKING_RETRIES = 120
|
|
45
46
|
|
|
46
47
|
def __init__(
|
|
47
|
-
self, subcommand: str, base_url: str, api_key: str
|
|
48
|
+
self, subcommand: str, base_url: str, api_key: Union[str, None], snapend_id: Union[str, None],
|
|
48
49
|
# Enumerate, Clone
|
|
49
|
-
game_id: str
|
|
50
|
+
game_id: Union[str, None],
|
|
50
51
|
# Clone
|
|
51
|
-
name: str
|
|
52
|
-
env: str
|
|
52
|
+
name: Union[str, None],
|
|
53
|
+
env: Union[str, None],
|
|
53
54
|
# Clone, Apply, Promote
|
|
54
|
-
manifest_path: str
|
|
55
|
+
manifest_path: Union[str, None],
|
|
55
56
|
# Download
|
|
56
|
-
category: str, platform_type: str, protos_category: str, auth_type: str, snaps: str
|
|
57
|
+
category: str, platform_type: str, protos_category: str, auth_type: str, snaps: Union[str, None],
|
|
57
58
|
# Clone, Apply, Promote, Download
|
|
58
|
-
out_path: str
|
|
59
|
+
out_path: Union[str, None],
|
|
59
60
|
# Update
|
|
60
|
-
byosnaps: str
|
|
61
|
+
byosnaps: Union[str, None], byogs: Union[str, None], blocking: bool = False
|
|
61
62
|
) -> None:
|
|
62
63
|
self.subcommand: str = subcommand
|
|
63
64
|
self.base_url: str = base_url
|
|
64
65
|
self.api_key: str = api_key
|
|
65
66
|
self.snapend_id: str = snapend_id
|
|
66
|
-
self.game_id: str
|
|
67
|
+
self.game_id: Union[str, None] = game_id
|
|
67
68
|
self.name: str = name
|
|
68
69
|
self.env: str = env
|
|
69
|
-
self.manifest_path: str
|
|
70
|
-
self.manifest_file_name: str
|
|
70
|
+
self.manifest_path: Union[str, None] = manifest_path
|
|
71
|
+
self.manifest_file_name: Union[str, None] = Snapend._get_manifest_file_name(
|
|
71
72
|
manifest_path
|
|
72
73
|
)
|
|
73
74
|
self.category: str = category
|
|
74
75
|
self.download_types: Union[
|
|
75
|
-
|
|
76
|
+
Dict[str, Dict[str, str]], None
|
|
76
77
|
] = Snapend._make_download_type(category)
|
|
77
78
|
self.protos_category: str = protos_category
|
|
78
79
|
self.auth_type: str = auth_type
|
|
79
80
|
self.platform_type: str = platform_type
|
|
80
|
-
self.out_path: str
|
|
81
|
-
self.snaps: str
|
|
81
|
+
self.out_path: Union[str, None] = out_path
|
|
82
|
+
self.snaps: Union[str, None] = snaps
|
|
82
83
|
self.byosnap_list: Union[list, None] = Snapend._make_byosnap_list(
|
|
83
84
|
byosnaps) if byosnaps else None
|
|
84
|
-
self.byogs_list: str
|
|
85
|
+
self.byogs_list: Union[str, None] = Snapend._make_byogs_list(
|
|
85
86
|
byogs) if byogs else None
|
|
86
87
|
self.blocking: bool = blocking
|
|
87
88
|
# Validate input
|
|
@@ -90,7 +91,7 @@ class Snapend:
|
|
|
90
91
|
# Helpers
|
|
91
92
|
|
|
92
93
|
@staticmethod
|
|
93
|
-
def _get_manifest_file_name(manifest_path: str) -> str
|
|
94
|
+
def _get_manifest_file_name(manifest_path: str) -> Union[str, None]:
|
|
94
95
|
if manifest_path and manifest_path != '' and os.path.isfile(manifest_path):
|
|
95
96
|
file_name = os.path.basename(manifest_path)
|
|
96
97
|
if file_name.endswith('.json') or file_name.endswith('.yml') or \
|
|
@@ -181,7 +182,7 @@ class Snapend:
|
|
|
181
182
|
self.category = download_category
|
|
182
183
|
self.platform_type = platform_type
|
|
183
184
|
self.download_types: Union[
|
|
184
|
-
|
|
185
|
+
Dict[str, Dict[str, str]], None
|
|
185
186
|
] = Snapend._make_download_type(download_category)
|
|
186
187
|
|
|
187
188
|
def _execute_download(self) -> bool:
|
|
@@ -191,13 +192,15 @@ class Snapend:
|
|
|
191
192
|
f"download?category={self.category}"
|
|
192
193
|
)
|
|
193
194
|
if self.category not in Snapend.DOWNLOAD_TYPE_NOT_REQUIRED:
|
|
194
|
-
url +=
|
|
195
|
+
url += "&type=" + \
|
|
196
|
+
f"{self.download_types[self.platform_type]['type']}"
|
|
195
197
|
# If Protos, add protos category
|
|
196
198
|
if self.category == 'protos':
|
|
197
199
|
url += f"&subtype={self.protos_category}"
|
|
198
200
|
# If client or server SDK, add sub type and auth type
|
|
199
201
|
if self.category in ['client-sdk', 'server-sdk']:
|
|
200
|
-
url +=
|
|
202
|
+
url += "&subtype=" + \
|
|
203
|
+
f"{self.download_types[self.platform_type]['subtype']}"
|
|
201
204
|
url_auth_type: str = 'user'
|
|
202
205
|
if self.category == 'server-sdk' and self.auth_type == 'app':
|
|
203
206
|
url_auth_type = 'app'
|
|
@@ -212,20 +215,14 @@ class Snapend:
|
|
|
212
215
|
if self.category == 'admin-settings':
|
|
213
216
|
fn = f"snapser-{self.snapend_id}-admin-settings.json"
|
|
214
217
|
elif self.category == 'snapend-manifest':
|
|
215
|
-
fn =
|
|
216
|
-
f"
|
|
217
|
-
f"manifest.{self.download_types[self.platform_type]['type']}"
|
|
218
|
-
)
|
|
218
|
+
fn = f"snapser-{self.snapend_id}-manifest." + \
|
|
219
|
+
f"{self.download_types[self.platform_type]['type']}"
|
|
219
220
|
elif self.category == 'protos':
|
|
220
|
-
fn =
|
|
221
|
-
f"snapser-{self.snapend_id}-{self.category}"
|
|
221
|
+
fn = f"snapser-{self.snapend_id}-{self.category}" + \
|
|
222
222
|
f"-{self.platform_type}-{self.protos_category}.zip"
|
|
223
|
-
)
|
|
224
223
|
else:
|
|
225
|
-
fn =
|
|
226
|
-
f"snapser-{self.snapend_id}-{self.category}"
|
|
224
|
+
fn = f"snapser-{self.snapend_id}-{self.category}" + \
|
|
227
225
|
f"-{self.platform_type}-{self.auth_type}.zip"
|
|
228
|
-
)
|
|
229
226
|
if self.out_path is not None:
|
|
230
227
|
file_save_path = os.path.join(self.out_path, fn)
|
|
231
228
|
else:
|
|
@@ -256,7 +253,8 @@ class Snapend:
|
|
|
256
253
|
# Check subcommand
|
|
257
254
|
if not self.subcommand in Snapend.SUBCOMMANDS:
|
|
258
255
|
snapctl_error(
|
|
259
|
-
|
|
256
|
+
"Invalid command. Valid commands are " +
|
|
257
|
+
f"{', '.join(Snapend.SUBCOMMANDS)}.",
|
|
260
258
|
SNAPCTL_INPUT_ERROR
|
|
261
259
|
)
|
|
262
260
|
if self.subcommand == 'enumerate':
|
|
@@ -279,11 +277,23 @@ class Snapend:
|
|
|
279
277
|
if not self.manifest_path:
|
|
280
278
|
snapctl_error(
|
|
281
279
|
"Missing required parameter: manifest_path", SNAPCTL_INPUT_ERROR)
|
|
280
|
+
if not os.path.isfile(self.manifest_path):
|
|
281
|
+
snapctl_error(
|
|
282
|
+
f"Invalid path {
|
|
283
|
+
self.manifest_path}. Please enter a valid path to the manifest file",
|
|
284
|
+
SNAPCTL_INPUT_ERROR
|
|
285
|
+
)
|
|
282
286
|
elif self.subcommand == 'apply':
|
|
283
287
|
if not self.manifest_path:
|
|
284
288
|
snapctl_error(
|
|
285
289
|
"Missing required parameter: manifest_path", SNAPCTL_INPUT_ERROR)
|
|
286
290
|
raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
|
|
291
|
+
if not os.path.isfile(self.manifest_path):
|
|
292
|
+
snapctl_error(
|
|
293
|
+
f"Invalid path {
|
|
294
|
+
self.manifest_path}. Please enter a valid path to the manifest file",
|
|
295
|
+
SNAPCTL_INPUT_ERROR
|
|
296
|
+
)
|
|
287
297
|
if not self.manifest_file_name:
|
|
288
298
|
snapctl_error(
|
|
289
299
|
"Invalid manifest file. Supported formats are .json, .yml, .yaml",
|
|
@@ -426,15 +436,16 @@ class Snapend:
|
|
|
426
436
|
'Snapend clone successful. Do not forget to download the latest manifest.',
|
|
427
437
|
progress)
|
|
428
438
|
snapctl_error(
|
|
429
|
-
'Snapend clone has been initiated but the Snapend is not up yet.'
|
|
439
|
+
'Snapend clone has been initiated but the Snapend is not up yet.' +
|
|
430
440
|
'Please try checking the status of the Snapend in some time',
|
|
431
441
|
SNAPCTL_SNAPEND_CLONE_TIMEOUT_ERROR,
|
|
432
442
|
progress
|
|
433
443
|
)
|
|
434
444
|
snapctl_success(
|
|
435
|
-
"Snapend clone has been initiated. "
|
|
436
|
-
"You can check the status using "
|
|
437
|
-
|
|
445
|
+
"Snapend clone has been initiated. " +
|
|
446
|
+
"You can check the status using " +
|
|
447
|
+
"`snapctl snapend state --snapend-id" +
|
|
448
|
+
f"{response['cluster']['id']}`",
|
|
438
449
|
progress
|
|
439
450
|
)
|
|
440
451
|
except RequestException as e:
|
|
@@ -488,18 +499,19 @@ class Snapend:
|
|
|
488
499
|
# self.manifest_file_name.split('.')[-1])
|
|
489
500
|
# self._execute_download()
|
|
490
501
|
snapctl_success(
|
|
491
|
-
'Snapend apply successful. Do not forget to download '
|
|
502
|
+
'Snapend apply successful. Do not forget to download ' +
|
|
492
503
|
'the latest manifest.',
|
|
493
504
|
progress)
|
|
494
505
|
snapctl_error(
|
|
495
|
-
'Snapend apply has been initiated but the Snapend is not up yet.'
|
|
506
|
+
'Snapend apply has been initiated but the Snapend is not up yet.' +
|
|
496
507
|
'Please try checking the status of the Snapend in some time',
|
|
497
508
|
SNAPCTL_SNAPEND_APPLY_TIMEOUT_ERROR, progress
|
|
498
509
|
)
|
|
499
510
|
snapctl_success(
|
|
500
|
-
"Snapend apply has been initiated. "
|
|
501
|
-
"You can check the status using "
|
|
502
|
-
|
|
511
|
+
"Snapend apply has been initiated. " +
|
|
512
|
+
"You can check the status using " +
|
|
513
|
+
"`snapctl snapend state --snapend-id" +
|
|
514
|
+
f"{response['cluster']['id']}`",
|
|
503
515
|
progress
|
|
504
516
|
)
|
|
505
517
|
except RequestException as e:
|
|
@@ -552,20 +564,21 @@ class Snapend:
|
|
|
552
564
|
# self._execute_download()
|
|
553
565
|
# Fetch the new manifest
|
|
554
566
|
snapctl_success(
|
|
555
|
-
'Snapend promote successful. Do not forget to '
|
|
567
|
+
'Snapend promote successful. Do not forget to ' +
|
|
556
568
|
'download the latest manifest.',
|
|
557
569
|
progress
|
|
558
570
|
)
|
|
559
571
|
snapctl_error(
|
|
560
|
-
'Snapend apply has been initiated but the Snapend is not up yet.'
|
|
572
|
+
'Snapend apply has been initiated but the Snapend is not up yet.' +
|
|
561
573
|
'Please try checking the status of the Snapend in some time',
|
|
562
574
|
SNAPCTL_SNAPEND_PROMOTE_TIMEOUT_ERROR,
|
|
563
575
|
progress
|
|
564
576
|
)
|
|
565
577
|
snapctl_success(
|
|
566
|
-
"Snapend apply has been initiated. "
|
|
567
|
-
"You can check the status using "
|
|
568
|
-
|
|
578
|
+
"Snapend apply has been initiated. " +
|
|
579
|
+
"You can check the status using " +
|
|
580
|
+
"`snapctl snapend state --snapend-id" +
|
|
581
|
+
f"{response['cluster']['id']}`",
|
|
569
582
|
progress
|
|
570
583
|
)
|
|
571
584
|
snapctl_error(f'Unable to promote the manifest. Reason: {res.text}',
|
|
@@ -593,7 +606,8 @@ class Snapend:
|
|
|
593
606
|
try:
|
|
594
607
|
if self._execute_download():
|
|
595
608
|
snapctl_success(
|
|
596
|
-
|
|
609
|
+
"Snapend download successful. " +
|
|
610
|
+
f"{self.category} saved at {self.out_path}",
|
|
597
611
|
progress
|
|
598
612
|
)
|
|
599
613
|
except RequestException as e:
|
|
@@ -636,19 +650,19 @@ class Snapend:
|
|
|
636
650
|
# self.manifest_file_name.split('.')[-1])
|
|
637
651
|
# self._execute_download()
|
|
638
652
|
snapctl_success(
|
|
639
|
-
'Snapend update successful. Do not forget to '
|
|
653
|
+
'Snapend update successful. Do not forget to ' +
|
|
640
654
|
'download the latest manifest.',
|
|
641
655
|
progress
|
|
642
656
|
)
|
|
643
657
|
snapctl_error(
|
|
644
|
-
'Snapend update has been initiated. '
|
|
658
|
+
'Snapend update has been initiated. ' +
|
|
645
659
|
'You can check the status using `snapctl snapend state`',
|
|
646
660
|
SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR,
|
|
647
661
|
progress
|
|
648
662
|
)
|
|
649
663
|
snapctl_success(
|
|
650
|
-
"Snapend update has been initiated. "
|
|
651
|
-
"You can check the status using "
|
|
664
|
+
"Snapend update has been initiated. " +
|
|
665
|
+
"You can check the status using " +
|
|
652
666
|
f"`snapctl snapend state --snapend-id {self.snapend_id}`",
|
|
653
667
|
progress
|
|
654
668
|
)
|
|
@@ -678,7 +692,8 @@ class Snapend:
|
|
|
678
692
|
current_state = self._get_snapend_state()
|
|
679
693
|
if current_state != 'INVALID':
|
|
680
694
|
snapctl_success(
|
|
681
|
-
|
|
695
|
+
'Snapend get state successful. Current snapend state is: ' +
|
|
696
|
+
f'{current_state}',
|
|
682
697
|
progress)
|
|
683
698
|
snapctl_error("Unable to get the snapend state.",
|
|
684
699
|
SNAPCTL_SNAPEND_STATE_ERROR, progress)
|
snapctl/config/constants.py
CHANGED
snapctl/config/hashes.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
|
|
1
3
|
"""
|
|
2
4
|
This file contains the hashes / list constants
|
|
3
5
|
"""
|
|
4
|
-
CLIENT_SDK_TYPES:
|
|
6
|
+
CLIENT_SDK_TYPES: Dict[str, Dict[str, str]] = {
|
|
5
7
|
'unity': {
|
|
6
8
|
'type': 'csharp',
|
|
7
9
|
'subtype': 'unity',
|
|
@@ -52,7 +54,7 @@ CLIENT_SDK_TYPES: dict[str, dict[str, str]] = {
|
|
|
52
54
|
},
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
SERVER_SDK_TYPES:
|
|
57
|
+
SERVER_SDK_TYPES: Dict[str, Dict[str, str]] = {
|
|
56
58
|
'csharp': {
|
|
57
59
|
'type': 'csharp',
|
|
58
60
|
'subtype': '',
|
|
@@ -119,7 +121,7 @@ SERVER_SDK_TYPES: dict[str, dict[str, str]] = {
|
|
|
119
121
|
},
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
PROTOS_TYPES:
|
|
124
|
+
PROTOS_TYPES: Dict[str, Dict[str, str]] = {
|
|
123
125
|
'cpp': {
|
|
124
126
|
'type': 'cpp',
|
|
125
127
|
'subtype': '',
|
|
@@ -138,7 +140,7 @@ PROTOS_TYPES: dict[str, dict[str, str]] = {
|
|
|
138
140
|
},
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
SNAPEND_MANIFEST_TYPES:
|
|
143
|
+
SNAPEND_MANIFEST_TYPES: Dict[str, Dict[str, str]] = {
|
|
142
144
|
'json': {
|
|
143
145
|
'type': 'json',
|
|
144
146
|
'subtype': '',
|
|
@@ -149,14 +151,14 @@ SNAPEND_MANIFEST_TYPES: dict[str, dict[str, str]] = {
|
|
|
149
151
|
},
|
|
150
152
|
}
|
|
151
153
|
|
|
152
|
-
SERVICE_IDS:
|
|
154
|
+
SERVICE_IDS: List[str] = [
|
|
153
155
|
'analytics', 'auth', 'client-logs', 'events', 'experiments', 'gdpr', 'guilds', 'hades', 'iap',
|
|
154
156
|
'inventory', 'leaderboards', 'matchmaking', 'notifications', 'parties', 'profiles', 'quests',
|
|
155
157
|
'relay', 'remote-config', 'scheduler', 'sequencer', 'social-graph', 'statistics', 'storage',
|
|
156
158
|
'trackables', 'xp'
|
|
157
159
|
]
|
|
158
160
|
|
|
159
|
-
DEFAULT_BYOSNAP_DEV_TEMPLATE = {
|
|
161
|
+
DEFAULT_BYOSNAP_DEV_TEMPLATE: Dict[str, object] = {
|
|
160
162
|
'cpu': 100,
|
|
161
163
|
'memory': 0.125,
|
|
162
164
|
'min_replicas': 1,
|
|
@@ -165,7 +167,7 @@ DEFAULT_BYOSNAP_DEV_TEMPLATE = {
|
|
|
165
167
|
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "DEVELOPMENT"}]
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
DEFAULT_BYOSNAP_STAGE_TEMPLATE = {
|
|
170
|
+
DEFAULT_BYOSNAP_STAGE_TEMPLATE: Dict[str, object] = {
|
|
169
171
|
'cpu': 100,
|
|
170
172
|
'memory': 0.125,
|
|
171
173
|
'min_replicas': 1,
|
|
@@ -174,7 +176,7 @@ DEFAULT_BYOSNAP_STAGE_TEMPLATE = {
|
|
|
174
176
|
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "STAGING"}]
|
|
175
177
|
}
|
|
176
178
|
|
|
177
|
-
DEFAULT_BYOSNAP_PROD_TEMPLATE = {
|
|
179
|
+
DEFAULT_BYOSNAP_PROD_TEMPLATE: Dict[str, object] = {
|
|
178
180
|
'cpu': 100,
|
|
179
181
|
'memory': 0.125,
|
|
180
182
|
'min_replicas': 2,
|
|
@@ -183,13 +185,13 @@ DEFAULT_BYOSNAP_PROD_TEMPLATE = {
|
|
|
183
185
|
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "PRODUCTION"}]
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
BYOSNAP_TEMPLATE = {
|
|
188
|
+
BYOSNAP_TEMPLATE: Dict[str, Dict[str, object]] = {
|
|
187
189
|
'dev_template': DEFAULT_BYOSNAP_DEV_TEMPLATE,
|
|
188
190
|
'stage_template': DEFAULT_BYOSNAP_STAGE_TEMPLATE,
|
|
189
191
|
'prod_template': DEFAULT_BYOSNAP_PROD_TEMPLATE
|
|
190
192
|
}
|
|
191
193
|
|
|
192
|
-
ARCHITECTURE_MAPPING:
|
|
194
|
+
ARCHITECTURE_MAPPING: Dict[str, str] = {
|
|
193
195
|
'x86_64': 'amd64',
|
|
194
196
|
'arm64': 'arm64',
|
|
195
197
|
'aarch64': 'arm64',
|
snapctl/main.py
CHANGED
|
@@ -44,7 +44,7 @@ app = typer.Typer(
|
|
|
44
44
|
######### HELPER METHODS #########
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def extract_config(extract_key: str, profile: str
|
|
47
|
+
def extract_config(extract_key: str, profile: Union[str, None] = None) -> object:
|
|
48
48
|
"""
|
|
49
49
|
Extracts the API Key from the environment variable and if not present from the config file
|
|
50
50
|
"""
|
|
@@ -58,9 +58,9 @@ def extract_config(extract_key: str, profile: str | None = None) -> object:
|
|
|
58
58
|
result['location'] = 'environment-variable'
|
|
59
59
|
result['value'] = env_api_key
|
|
60
60
|
return result
|
|
61
|
-
encoding: str
|
|
61
|
+
encoding: Union[str, None] = "utf-8-sig" if platform == 'win32' else None
|
|
62
62
|
# Option 2 - Get the API Key from CONFIG PATH environment variable
|
|
63
|
-
config_file_path: str
|
|
63
|
+
config_file_path: Union[str, None] = os.getenv(CONFIG_PATH_KEY)
|
|
64
64
|
# Option 3 - Get the API Key from the hardcoded config file we look for
|
|
65
65
|
if config_file_path is None:
|
|
66
66
|
if platform == 'win32':
|
|
@@ -76,8 +76,8 @@ def extract_config(extract_key: str, profile: str | None = None) -> object:
|
|
|
76
76
|
result['location'] = f'"{config_file_path}:profile {profile}"'
|
|
77
77
|
config_profile = f'profile {profile}'
|
|
78
78
|
info(
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
'Trying to extract API KEY from ' +
|
|
80
|
+
f'{config_file_path}:profile {profile}"'
|
|
81
81
|
)
|
|
82
82
|
result['value'] = config.get(
|
|
83
83
|
config_profile, extract_key, fallback=None, raw=True
|
|
@@ -88,7 +88,7 @@ def extract_config(extract_key: str, profile: str | None = None) -> object:
|
|
|
88
88
|
return result
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
def get_base_url(api_key: str
|
|
91
|
+
def get_base_url(api_key: Union[str, None]) -> str:
|
|
92
92
|
"""
|
|
93
93
|
Returns the base url based on the api_key
|
|
94
94
|
"""
|
|
@@ -141,7 +141,7 @@ def default_context_callback(ctx: typer.Context):
|
|
|
141
141
|
|
|
142
142
|
def api_key_context_callback(
|
|
143
143
|
ctx: typer.Context,
|
|
144
|
-
api_key: str
|
|
144
|
+
api_key: Union[str, None] = None
|
|
145
145
|
):
|
|
146
146
|
"""
|
|
147
147
|
Callback to set the context for the api_key
|
|
@@ -160,7 +160,7 @@ def api_key_context_callback(
|
|
|
160
160
|
|
|
161
161
|
def profile_context_callback(
|
|
162
162
|
ctx: typer.Context,
|
|
163
|
-
profile: str
|
|
163
|
+
profile: Union[str, None] = None
|
|
164
164
|
):
|
|
165
165
|
"""
|
|
166
166
|
Callback to set the context for the profile
|
snapctl/utils/helper.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Helper functions for snapctl
|
|
3
3
|
"""
|
|
4
|
+
from typing import Union, Dict
|
|
4
5
|
import re
|
|
5
6
|
import requests
|
|
6
7
|
import typer
|
|
@@ -12,7 +13,7 @@ from snapctl.config.hashes import ARCHITECTURE_MAPPING
|
|
|
12
13
|
from snapctl.utils.echo import error, success
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
def validate_api_key(base_url: str, api_key: str
|
|
16
|
+
def validate_api_key(base_url: str, api_key: Union[str, None]) -> bool:
|
|
16
17
|
"""
|
|
17
18
|
This function validates the API Key
|
|
18
19
|
"""
|
|
@@ -45,7 +46,7 @@ def validate_api_key(base_url: str, api_key: str | None) -> bool:
|
|
|
45
46
|
raise typer.Exit(code=SNAPCTL_CONFIGURATION_ERROR)
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
def get_composite_token(base_url: str, api_key: str
|
|
49
|
+
def get_composite_token(base_url: str, api_key: Union[str, None], action: str, params: object) -> str:
|
|
49
50
|
"""
|
|
50
51
|
This function exchanges the api_key for a composite token.
|
|
51
52
|
"""
|
|
@@ -76,7 +77,7 @@ def get_composite_token(base_url: str, api_key: str | None, action: str, params:
|
|
|
76
77
|
return res.json()['token']
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
def check_dockerfile_architecture(dockerfile_path: str, system_arch: str) ->
|
|
80
|
+
def check_dockerfile_architecture(dockerfile_path: str, system_arch: str) -> Dict[str, object]:
|
|
80
81
|
"""
|
|
81
82
|
Check the Dockerfile for architecture specific commands
|
|
82
83
|
"""
|
|
@@ -113,14 +114,11 @@ def check_dockerfile_architecture(dockerfile_path: str, system_arch: str) -> dic
|
|
|
113
114
|
match = re.search(pattern, line)
|
|
114
115
|
if match and ARCHITECTURE_MAPPING.get(match.group(1)) != system_arch:
|
|
115
116
|
response['error'] = True
|
|
116
|
-
response['message'] =
|
|
117
|
-
f'
|
|
118
|
-
|
|
119
|
-
f'
|
|
120
|
-
f'
|
|
121
|
-
match.group(1)}, which does not match the '
|
|
122
|
-
f' systems ({system_arch}).'
|
|
123
|
-
)
|
|
117
|
+
response['message'] = '[Architecture Mismatch] Line ' + \
|
|
118
|
+
f'{line_number}: "{line.strip()}" ' + \
|
|
119
|
+
f'of Dockerfile {dockerfile_path} ' + \
|
|
120
|
+
f'specifies architecture {match.group(1)}, which does not match the ' + \
|
|
121
|
+
f'systems ({system_arch}).'
|
|
124
122
|
return response
|
|
125
123
|
except FileNotFoundError:
|
|
126
124
|
response['error'] = True
|
|
@@ -133,7 +131,7 @@ def check_dockerfile_architecture(dockerfile_path: str, system_arch: str) -> dic
|
|
|
133
131
|
return response
|
|
134
132
|
|
|
135
133
|
|
|
136
|
-
def snapctl_success(message: str, progress: Progress
|
|
134
|
+
def snapctl_success(message: str, progress: Union[Progress, None] = None, no_exit: bool = False):
|
|
137
135
|
"""
|
|
138
136
|
This function exits the snapctl
|
|
139
137
|
"""
|
|
@@ -144,7 +142,7 @@ def snapctl_success(message: str, progress: Progress | None = None, no_exit: boo
|
|
|
144
142
|
raise typer.Exit(code=SNAPCTL_SUCCESS)
|
|
145
143
|
|
|
146
144
|
|
|
147
|
-
def snapctl_error(message: str, code: int, progress: Progress
|
|
145
|
+
def snapctl_error(message: str, code: int, progress: Union[Progress, None] = None):
|
|
148
146
|
"""
|
|
149
147
|
This function exits the snapctl
|
|
150
148
|
"""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
snapctl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
snapctl/__main__.py,sha256=43jKoTk8b85hk_MT6499N3ruHdEfM8WBImd_-3VzjI8,116
|
|
3
|
+
snapctl/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
snapctl/commands/byogs.py,sha256=XdF8Eq8vDzKFZzQzeRAbApTK8HwXBGwe64lcWNBu-dQ,13515
|
|
5
|
+
snapctl/commands/byosnap.py,sha256=Z-yf7ssdvUnycIcZDN1JXZ-CO5gjq6yQZ7_bb6KYAeQ,31207
|
|
6
|
+
snapctl/commands/game.py,sha256=icAPD8derxtgXHZQvziHd1O8fwD5Kw7HFMA8yXOUSRQ,4344
|
|
7
|
+
snapctl/commands/generate.py,sha256=7z4nyqDuAieFmIg-XVIri2xkXPpDJd0E3uKYIfQtBqE,7891
|
|
8
|
+
snapctl/commands/snapend.py,sha256=wEeA9v0SCs0G2093wMIKVTQhPLCfx8i5Ladk9kMlSCM,30729
|
|
9
|
+
snapctl/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
snapctl/config/constants.py,sha256=s26pXoQWuafLkvtFtOv5sBHrAsZjVO3MUsG3AA3JqGQ,2735
|
|
11
|
+
snapctl/config/endpoints.py,sha256=VAeOmx3k3ukB-9XuGI65KtCJwFK-KFgzor-UWE8JU0g,297
|
|
12
|
+
snapctl/config/hashes.py,sha256=7jkMYfMAcgdque5PN10-B3QqwoXvtsuJKJr9dKZUvJ8,4139
|
|
13
|
+
snapctl/main.py,sha256=aaFB0insVsIKDp25Hc0J0t5JtIQJXxDgHbBwKaHVbBc,19619
|
|
14
|
+
snapctl/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
snapctl/types/definitions.py,sha256=EQzLeiXkJ8ISRlCqHMviNVsWWpmhWjpKaOBLdlvOTmY,644
|
|
16
|
+
snapctl/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
snapctl/utils/echo.py,sha256=V0qgjqqGXRiueMkq31enmNmdqciC8S90qGRcK8UupXA,1090
|
|
18
|
+
snapctl/utils/helper.py,sha256=XSn0x46mED86kQU1UlmuvJY9GsXO3Ncoba18Lb6FE8k,5522
|
|
19
|
+
snapctl-0.38.1.dist-info/LICENSE,sha256=6AcXm54KFSpmUI1ji9NIBd4Xl-DtjTqiyjBzfVb_CEk,2804
|
|
20
|
+
snapctl-0.38.1.dist-info/METADATA,sha256=HGOdEApmi0QmDIvWhSDUIO072EdxaOsGWzMO2eeoLJQ,21465
|
|
21
|
+
snapctl-0.38.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
22
|
+
snapctl-0.38.1.dist-info/entry_points.txt,sha256=tkKW9MzmFdRs6Bgkv29G78i9WEBK4WIOWunPfe3t2Wg,44
|
|
23
|
+
snapctl-0.38.1.dist-info/RECORD,,
|
snapctl-0.38.0.dist-info/RECORD
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
snapctl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
snapctl/__main__.py,sha256=43jKoTk8b85hk_MT6499N3ruHdEfM8WBImd_-3VzjI8,116
|
|
3
|
-
snapctl/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
snapctl/commands/byogs.py,sha256=yR8OViiTudweUWp0cS3bzERiEd4YqZTCNSEi2Sww2AE,13491
|
|
5
|
-
snapctl/commands/byosnap.py,sha256=MkohY7VOpnmxQgRJua7VocFVI-86_0gGL-HB6IRpu3s,31126
|
|
6
|
-
snapctl/commands/game.py,sha256=7255xoGszkk2pPcc2sRJP98-3S0qfSKXFOl5CrsbCSY,4349
|
|
7
|
-
snapctl/commands/generate.py,sha256=l1avy7YlCgscCBT40yh9L8OjD7ONMUE96BB2M553g30,7849
|
|
8
|
-
snapctl/commands/snapend.py,sha256=cxBMNMfXyQeLdg5NyKZ2ujjUG7zYxOgyjmeAoD27t7I,29922
|
|
9
|
-
snapctl/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
snapctl/config/constants.py,sha256=GabhULhawD_uBWQ9P6PIgb2RPG3LVC55hfwa2Ta0Jtg,2735
|
|
11
|
-
snapctl/config/endpoints.py,sha256=VAeOmx3k3ukB-9XuGI65KtCJwFK-KFgzor-UWE8JU0g,297
|
|
12
|
-
snapctl/config/hashes.py,sha256=x1OIgY9bKxJ7mn3sT5NFK8JzVy17rPI7J7sCfbEE1uc,4021
|
|
13
|
-
snapctl/main.py,sha256=DcOZJ8bwqzCNrjaI1ERm-4YMeRNMH6KP0tgxLpr_Ujs,19584
|
|
14
|
-
snapctl/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
snapctl/types/definitions.py,sha256=EQzLeiXkJ8ISRlCqHMviNVsWWpmhWjpKaOBLdlvOTmY,644
|
|
16
|
-
snapctl/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
snapctl/utils/echo.py,sha256=V0qgjqqGXRiueMkq31enmNmdqciC8S90qGRcK8UupXA,1090
|
|
18
|
-
snapctl/utils/helper.py,sha256=6z-rCVbxv7ETBxDbEfqwMJDMcKo1IBytsDz2J9-7S-U,5532
|
|
19
|
-
snapctl-0.38.0.dist-info/LICENSE,sha256=6AcXm54KFSpmUI1ji9NIBd4Xl-DtjTqiyjBzfVb_CEk,2804
|
|
20
|
-
snapctl-0.38.0.dist-info/METADATA,sha256=o-8Uax51WUDTm9TuKseF70jhmanSOtljlQe7f0fVDN4,21465
|
|
21
|
-
snapctl-0.38.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
22
|
-
snapctl-0.38.0.dist-info/entry_points.txt,sha256=tkKW9MzmFdRs6Bgkv29G78i9WEBK4WIOWunPfe3t2Wg,44
|
|
23
|
-
snapctl-0.38.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|