snapctl 0.43.2__py3-none-any.whl → 0.46.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 +37 -18
- snapctl/commands/byosnap.py +623 -222
- snapctl/commands/generate.py +3 -71
- snapctl/commands/release_notes.py +65 -0
- snapctl/commands/snapend.py +91 -76
- snapctl/config/constants.py +11 -9
- snapctl/config/hashes.py +18 -25
- snapctl/data/profiles/snapser-byosnap-profile.json +62 -0
- snapctl/data/profiles/snapser-byosnap-profile.yaml +54 -0
- snapctl/data/releases/beta-0.46.0.mdx +55 -0
- snapctl/main.py +81 -67
- {snapctl-0.43.2.dist-info → snapctl-0.46.0.dist-info}/METADATA +199 -98
- snapctl-0.46.0.dist-info/RECORD +27 -0
- snapctl-0.43.2.dist-info/RECORD +0 -23
- {snapctl-0.43.2.dist-info → snapctl-0.46.0.dist-info}/LICENSE +0 -0
- {snapctl-0.43.2.dist-info → snapctl-0.46.0.dist-info}/WHEEL +0 -0
- {snapctl-0.43.2.dist-info → snapctl-0.46.0.dist-info}/entry_points.txt +0 -0
snapctl/commands/generate.py
CHANGED
|
@@ -8,9 +8,8 @@ import os
|
|
|
8
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
|
-
SNAPCTL_GENERATE_GENERIC_ERROR,
|
|
11
|
+
SNAPCTL_GENERATE_GENERIC_ERROR, \
|
|
12
12
|
SNAPCTL_GENERATE_CREDENTIALS_ERROR
|
|
13
|
-
from snapctl.config.hashes import BYOSNAP_TEMPLATE
|
|
14
13
|
from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
|
|
15
14
|
|
|
16
15
|
|
|
@@ -18,12 +17,9 @@ class Generate:
|
|
|
18
17
|
"""
|
|
19
18
|
Generate CLI commands
|
|
20
19
|
"""
|
|
21
|
-
SUBCOMMANDS = ['
|
|
22
|
-
DEPRECATED_SOON_SUBCOMMANDS = ['byosnap-profile']
|
|
23
|
-
BYOSNAP_PROFILE_FN = 'snapser-byosnap-profile.json'
|
|
20
|
+
SUBCOMMANDS = ['credentials']
|
|
24
21
|
ECR_TOKEN_FN = 'snapser-ecr-credentials.json'
|
|
25
22
|
CATEGORIES = {
|
|
26
|
-
'profile': ['byosnap'],
|
|
27
23
|
'credentials': ['ecr']
|
|
28
24
|
}
|
|
29
25
|
|
|
@@ -68,19 +64,7 @@ class Generate:
|
|
|
68
64
|
code=SNAPCTL_INPUT_ERROR
|
|
69
65
|
)
|
|
70
66
|
# Check path
|
|
71
|
-
if self.subcommand == '
|
|
72
|
-
if self.category not in Generate.CATEGORIES['profile']:
|
|
73
|
-
snapctl_error(
|
|
74
|
-
message=f"Invalid category {self.category}. Valid category are " +
|
|
75
|
-
f"{Generate.CATEGORIES['profile']}",
|
|
76
|
-
code=SNAPCTL_INPUT_ERROR
|
|
77
|
-
)
|
|
78
|
-
if not self.out_path:
|
|
79
|
-
snapctl_error(
|
|
80
|
-
message="Path is required for profile generation",
|
|
81
|
-
code=SNAPCTL_INPUT_ERROR
|
|
82
|
-
)
|
|
83
|
-
elif self.subcommand == 'credentials':
|
|
67
|
+
if self.subcommand == 'credentials':
|
|
84
68
|
if self.category not in Generate.CATEGORIES['credentials']:
|
|
85
69
|
snapctl_error(
|
|
86
70
|
message=f"Invalid category {self.category}. Valid category are " +
|
|
@@ -100,58 +84,6 @@ class Generate:
|
|
|
100
84
|
code=SNAPCTL_INPUT_ERROR
|
|
101
85
|
)
|
|
102
86
|
|
|
103
|
-
def byosnap_profile(self, no_exit: bool = False) -> None:
|
|
104
|
-
"""
|
|
105
|
-
Generate snapser-byosnap-profile.json
|
|
106
|
-
"""
|
|
107
|
-
progress = Progress(
|
|
108
|
-
SpinnerColumn(),
|
|
109
|
-
TextColumn("[progress.description]{task.description}"),
|
|
110
|
-
transient=True,
|
|
111
|
-
)
|
|
112
|
-
progress.start()
|
|
113
|
-
progress.add_task(
|
|
114
|
-
description='Generating BYOSnap profile...', total=None)
|
|
115
|
-
try:
|
|
116
|
-
if self.out_path is not None:
|
|
117
|
-
file_save_path = os.path.join(
|
|
118
|
-
self.out_path, Generate.BYOSNAP_PROFILE_FN)
|
|
119
|
-
else:
|
|
120
|
-
file_save_path = os.path.join(
|
|
121
|
-
os.getcwd(), Generate.BYOSNAP_PROFILE_FN)
|
|
122
|
-
file_written = False
|
|
123
|
-
with open(file_save_path, "w") as file:
|
|
124
|
-
json.dump(BYOSNAP_TEMPLATE, file, indent=4)
|
|
125
|
-
file_written = True
|
|
126
|
-
if file_written:
|
|
127
|
-
snapctl_success(
|
|
128
|
-
message="BYOSNAP Profile generation successful. " +
|
|
129
|
-
f"{Generate.BYOSNAP_PROFILE_FN} saved at {file_save_path}",
|
|
130
|
-
progress=progress,
|
|
131
|
-
no_exit=no_exit
|
|
132
|
-
)
|
|
133
|
-
return
|
|
134
|
-
except (IOError, OSError) as file_error:
|
|
135
|
-
snapctl_error(
|
|
136
|
-
message=f"File error: {file_error}",
|
|
137
|
-
code=SNAPCTL_GENERATE_PROFILE_ERROR, progress=progress)
|
|
138
|
-
except json.JSONDecodeError as json_error:
|
|
139
|
-
snapctl_error(
|
|
140
|
-
message=f"JSON error: {json_error}",
|
|
141
|
-
code=SNAPCTL_GENERATE_PROFILE_ERROR, progress=progress)
|
|
142
|
-
snapctl_error(
|
|
143
|
-
message="Failed to generate BYOSNAP Profile",
|
|
144
|
-
code=SNAPCTL_GENERATE_PROFILE_ERROR,
|
|
145
|
-
progress=progress
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
def profile(self, no_exit: bool = False) -> None:
|
|
149
|
-
"""
|
|
150
|
-
Generate profile
|
|
151
|
-
"""
|
|
152
|
-
if self.category == 'byosnap':
|
|
153
|
-
self.byosnap_profile(no_exit)
|
|
154
|
-
|
|
155
87
|
def ecr_credentials(self, no_exit: bool = False) -> None:
|
|
156
88
|
"""
|
|
157
89
|
Generate credentials
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Release Notes Command
|
|
3
|
+
"""
|
|
4
|
+
import os
|
|
5
|
+
from typing import Union
|
|
6
|
+
from snapctl.config.constants import SNAPCTL_INPUT_ERROR
|
|
7
|
+
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ReleaseNotes:
|
|
11
|
+
"""
|
|
12
|
+
Release Notes Command
|
|
13
|
+
"""
|
|
14
|
+
SUBCOMMANDS = ["releases", "show"]
|
|
15
|
+
RELEASES_PATH = 'snapctl/data/releases'
|
|
16
|
+
|
|
17
|
+
def __init__(self, *, subcommand: str, version: Union[str, None] = None) -> None:
|
|
18
|
+
self.subcommand = subcommand
|
|
19
|
+
self.version = version
|
|
20
|
+
self.validate_input()
|
|
21
|
+
|
|
22
|
+
def validate_input(self) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Validate input
|
|
25
|
+
"""
|
|
26
|
+
if self.subcommand not in self.SUBCOMMANDS:
|
|
27
|
+
snapctl_error(
|
|
28
|
+
message="Invalid command. Valid commands are " +
|
|
29
|
+
f"{', '.join(ReleaseNotes.SUBCOMMANDS)}.",
|
|
30
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
31
|
+
|
|
32
|
+
# Upper echelon commands
|
|
33
|
+
def releases(self) -> None:
|
|
34
|
+
"""
|
|
35
|
+
List versions
|
|
36
|
+
"""
|
|
37
|
+
# List all files and directories in the specified path
|
|
38
|
+
files_and_directories = os.listdir(ReleaseNotes.RELEASES_PATH)
|
|
39
|
+
|
|
40
|
+
# Print only files, excluding subdirectories
|
|
41
|
+
print('== Releases ' + '=' * (92))
|
|
42
|
+
for item in files_and_directories:
|
|
43
|
+
if os.path.isfile(os.path.join(ReleaseNotes.RELEASES_PATH, item)):
|
|
44
|
+
print(item.replace('.mdx', '').replace('.md', ''))
|
|
45
|
+
print('=' * (104))
|
|
46
|
+
snapctl_success(message="List versions")
|
|
47
|
+
|
|
48
|
+
def show(self) -> None:
|
|
49
|
+
"""
|
|
50
|
+
Show version
|
|
51
|
+
"""
|
|
52
|
+
# Check if the specified version exists
|
|
53
|
+
version_file = os.path.join(
|
|
54
|
+
ReleaseNotes.RELEASES_PATH, f'{self.version}.mdx')
|
|
55
|
+
if not os.path.isfile(version_file):
|
|
56
|
+
snapctl_error(
|
|
57
|
+
message=f"Version {self.version} does not exist.",
|
|
58
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
59
|
+
|
|
60
|
+
# Read the contents of the specified version file
|
|
61
|
+
print('== Releases Notes ' + '=' * (86))
|
|
62
|
+
with open(version_file, 'r') as file:
|
|
63
|
+
print(file.read())
|
|
64
|
+
print('=' * (104))
|
|
65
|
+
snapctl_success(message=f"Show version {self.version}")
|
snapctl/commands/snapend.py
CHANGED
|
@@ -19,8 +19,8 @@ from snapctl.config.constants import SERVER_CALL_TIMEOUT, SNAPCTL_INPUT_ERROR, \
|
|
|
19
19
|
SNAPCTL_SNAPEND_PROMOTE_TIMEOUT_ERROR, SNAPCTL_SNAPEND_PROMOTE_ERROR, \
|
|
20
20
|
SNAPCTL_SNAPEND_DOWNLOAD_ERROR, SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR, \
|
|
21
21
|
SNAPCTL_SNAPEND_UPDATE_ERROR, SNAPCTL_SNAPEND_STATE_ERROR
|
|
22
|
-
from snapctl.config.hashes import
|
|
23
|
-
SNAPEND_MANIFEST_TYPES, SDK_TYPES
|
|
22
|
+
from snapctl.config.hashes import PROTOS_TYPES, CLIENT_SDK_TYPES, \
|
|
23
|
+
SNAPEND_MANIFEST_TYPES, SDK_TYPES, SDK_ACCESS_AUTH_TYPE_LOOKUP
|
|
24
24
|
from snapctl.utils.echo import error, success, info
|
|
25
25
|
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
26
26
|
|
|
@@ -34,13 +34,14 @@ class Snapend:
|
|
|
34
34
|
'download', 'update', 'state'
|
|
35
35
|
]
|
|
36
36
|
DOWNLOAD_CATEGORY = [
|
|
37
|
-
'sdk', 'protos',
|
|
38
|
-
'admin-settings', 'snapend-manifest'
|
|
37
|
+
'sdk', 'protos', 'snapend-manifest'
|
|
39
38
|
]
|
|
39
|
+
CATEGORY_TYPE_SDK = ['user', 'server', 'internal', 'app']
|
|
40
|
+
CATEGORY_TYPE_PROTOS = ['messages', 'services']
|
|
41
|
+
|
|
40
42
|
DOWNLOAD_TYPE_NOT_REQUIRED = ['admin-settings']
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
AUTH_TYPES = ['user', 'app']
|
|
43
|
+
# ACCESS_TYPES = ['external', 'internal']
|
|
44
|
+
# AUTH_TYPES = ['user', 'app']
|
|
44
45
|
ENV_TYPES = ['DEVELOPMENT', 'STAGING']
|
|
45
46
|
BLOCKING_CALL_SLEEP = 5
|
|
46
47
|
MAX_BLOCKING_RETRIES = 120
|
|
@@ -54,13 +55,11 @@ class Snapend:
|
|
|
54
55
|
name: Union[str, None] = None,
|
|
55
56
|
env: Union[str, None] = None,
|
|
56
57
|
# Clone, Apply, Promote
|
|
57
|
-
|
|
58
|
+
manifest_path_filename: Union[str, None] = None,
|
|
58
59
|
# Download
|
|
59
60
|
category: Union[str, None] = None,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
platform_type: Union[str, None] = None,
|
|
63
|
-
protos_category: Union[str, None] = None,
|
|
61
|
+
category_format: Union[str, None] = None,
|
|
62
|
+
category_type: Union[str, None] = None,
|
|
64
63
|
snaps: Union[str, None] = None,
|
|
65
64
|
# Clone, Apply, Promote, Download
|
|
66
65
|
out_path: Union[str, None] = None,
|
|
@@ -76,20 +75,19 @@ class Snapend:
|
|
|
76
75
|
self.game_id: Union[str, None] = game_id
|
|
77
76
|
self.name: str = name
|
|
78
77
|
self.env: str = env
|
|
79
|
-
self.
|
|
80
|
-
self.manifest_file_name: Union[str, None] = Snapend._get_manifest_file_name(
|
|
81
|
-
manifest_path
|
|
82
|
-
)
|
|
78
|
+
self.manifest_path_filename: Union[str, None] = manifest_path_filename
|
|
83
79
|
self.category: str = category
|
|
84
|
-
self.
|
|
85
|
-
self.
|
|
80
|
+
self.category_format: str = category_format
|
|
81
|
+
self.category_type: Union[str, None] = category_type
|
|
86
82
|
self.download_types: Union[
|
|
87
83
|
Dict[str, Dict[str, str]], None
|
|
88
84
|
] = Snapend._make_download_type(category)
|
|
89
|
-
self.protos_category: str = protos_category
|
|
90
|
-
self.platform_type: str = platform_type
|
|
91
85
|
self.out_path: Union[str, None] = out_path
|
|
92
86
|
self.snaps: Union[str, None] = snaps
|
|
87
|
+
# Values below are derived values
|
|
88
|
+
self.manifest_file_name: Union[str, None] = Snapend._get_manifest_file_name(
|
|
89
|
+
manifest_path_filename
|
|
90
|
+
)
|
|
93
91
|
self.byosnap_list: Union[list, None] = Snapend._make_byosnap_list(
|
|
94
92
|
byosnaps) if byosnaps else None
|
|
95
93
|
self.byogs_list: Union[str, None] = Snapend._make_byogs_list(
|
|
@@ -182,13 +180,13 @@ class Snapend:
|
|
|
182
180
|
def _assign_snapend_id(self, snapend_id: str) -> None:
|
|
183
181
|
self.snapend_id = snapend_id
|
|
184
182
|
|
|
185
|
-
def _setup_for_download(self,
|
|
183
|
+
def _setup_for_download(self, category_format: str) -> bool:
|
|
186
184
|
'''
|
|
187
185
|
Called by subcommands that want to initiate a download of the new manifest post update
|
|
188
186
|
'''
|
|
189
187
|
download_category: str = 'snapend-manifest'
|
|
190
188
|
self.category = download_category
|
|
191
|
-
self.
|
|
189
|
+
self.category_format = category_format
|
|
192
190
|
self.download_types: Union[
|
|
193
191
|
Dict[str, Dict[str, str]], None
|
|
194
192
|
] = Snapend._make_download_type(download_category)
|
|
@@ -201,20 +199,18 @@ class Snapend:
|
|
|
201
199
|
)
|
|
202
200
|
if self.category not in Snapend.DOWNLOAD_TYPE_NOT_REQUIRED:
|
|
203
201
|
url += "&type=" + \
|
|
204
|
-
f"{self.download_types[self.
|
|
202
|
+
f"{self.download_types[self.category_format]['type']}"
|
|
205
203
|
# If Protos, add protos category
|
|
206
204
|
if self.category == 'protos':
|
|
207
|
-
url += f"&subtype={self.
|
|
205
|
+
url += f"&subtype={self.category_type}"
|
|
208
206
|
# If client or server SDK, add sub type and auth type
|
|
209
|
-
if self.category
|
|
207
|
+
if self.category == 'sdk':
|
|
210
208
|
url += "&subtype=" + \
|
|
211
|
-
f"{self.download_types[self.
|
|
212
|
-
url += f"&access_type={self.
|
|
213
|
-
if self.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
url_auth_type = 'app'
|
|
217
|
-
url += f"&auth_type={url_auth_type}"
|
|
209
|
+
f"{self.download_types[self.category_format]['subtype']}"
|
|
210
|
+
url += f"&access_type={SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['access_type']}"
|
|
211
|
+
if 'auth_type' in SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type] and \
|
|
212
|
+
SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['auth_type'] != '':
|
|
213
|
+
url += f"&auth_type={SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['auth_type']}"
|
|
218
214
|
# Customize snaps
|
|
219
215
|
if self.snaps:
|
|
220
216
|
url += f"&snaps={self.snaps}"
|
|
@@ -226,15 +222,17 @@ class Snapend:
|
|
|
226
222
|
fn = f"snapser-{self.snapend_id}-admin-settings.json"
|
|
227
223
|
elif self.category == 'snapend-manifest':
|
|
228
224
|
fn = f"snapser-{self.snapend_id}-manifest." + \
|
|
229
|
-
f"{self.download_types[self.
|
|
225
|
+
f"{self.download_types[self.category_format]['type']}"
|
|
230
226
|
elif self.category == 'protos':
|
|
231
227
|
fn = f"snapser-{self.snapend_id}-{self.category}" + \
|
|
232
|
-
f"-{self.
|
|
228
|
+
f"-{self.category_format}-{self.category_type}.zip"
|
|
233
229
|
else:
|
|
234
230
|
fn = f"snapser-{self.snapend_id}-{self.category}" + \
|
|
235
|
-
f"-{self.
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
f"-{self.category_format}" + \
|
|
232
|
+
f"-{SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['access_type']}"
|
|
233
|
+
if 'auth_type' in SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type] and \
|
|
234
|
+
SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['auth_type'] != '':
|
|
235
|
+
fn += f"-{SDK_ACCESS_AUTH_TYPE_LOOKUP[self.category_type]['auth_type']}"
|
|
238
236
|
fn += ".zip"
|
|
239
237
|
if self.out_path is not None:
|
|
240
238
|
file_save_path = os.path.join(self.out_path, fn)
|
|
@@ -285,29 +283,34 @@ class Snapend:
|
|
|
285
283
|
snapctl_error(
|
|
286
284
|
message="Missing required parameter: name",
|
|
287
285
|
code=SNAPCTL_INPUT_ERROR)
|
|
286
|
+
if not self.env:
|
|
287
|
+
snapctl_error(
|
|
288
|
+
message="Missing required parameter: env", code=SNAPCTL_INPUT_ERROR)
|
|
288
289
|
if self.env.upper() not in Snapend.ENV_TYPES:
|
|
289
290
|
snapctl_error(
|
|
290
291
|
message="Invalid environment. Valid environments are " +
|
|
291
292
|
f"{', '.join(Snapend.ENV_TYPES)}.",
|
|
292
293
|
code=SNAPCTL_INPUT_ERROR
|
|
293
294
|
)
|
|
294
|
-
if not self.
|
|
295
|
+
if not self.manifest_path_filename:
|
|
295
296
|
snapctl_error(
|
|
296
|
-
message="Missing required parameter:
|
|
297
|
-
|
|
297
|
+
message="Missing required parameter: manifest_path_filename",
|
|
298
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
299
|
+
if not os.path.isfile(self.manifest_path_filename):
|
|
298
300
|
snapctl_error(
|
|
299
|
-
message=f"Invalid path {self.
|
|
301
|
+
message=f"Invalid path {self.manifest_path_filename}. " +
|
|
300
302
|
"Please enter a valid path to the manifest file",
|
|
301
303
|
code=SNAPCTL_INPUT_ERROR
|
|
302
304
|
)
|
|
303
305
|
elif self.subcommand == 'apply':
|
|
304
|
-
if not self.
|
|
306
|
+
if not self.manifest_path_filename:
|
|
305
307
|
snapctl_error(
|
|
306
|
-
message="Missing required parameter:
|
|
308
|
+
message="Missing required parameter: manifest_path_filename",
|
|
309
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
307
310
|
raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
|
|
308
|
-
if not os.path.isfile(self.
|
|
311
|
+
if not os.path.isfile(self.manifest_path_filename):
|
|
309
312
|
snapctl_error(
|
|
310
|
-
message=f"Invalid path {self.
|
|
313
|
+
message=f"Invalid path {self.manifest_path_filename}. " +
|
|
311
314
|
"Please enter a valid path to the manifest file",
|
|
312
315
|
code=SNAPCTL_INPUT_ERROR
|
|
313
316
|
)
|
|
@@ -328,50 +331,43 @@ class Snapend:
|
|
|
328
331
|
f"{', '.join(Snapend.DOWNLOAD_CATEGORY)}.",
|
|
329
332
|
code=SNAPCTL_INPUT_ERROR
|
|
330
333
|
)
|
|
334
|
+
if not self.category_format:
|
|
335
|
+
snapctl_error(
|
|
336
|
+
message="Missing required parameter: --format",
|
|
337
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
331
338
|
if self.category not in Snapend.DOWNLOAD_TYPE_NOT_REQUIRED and \
|
|
332
|
-
|
|
339
|
+
(self.download_types is None or self.category_format not in self.download_types):
|
|
333
340
|
snapctl_error(
|
|
334
|
-
message="Invalid Download
|
|
341
|
+
message="Invalid Download format.", code=SNAPCTL_INPUT_ERROR)
|
|
335
342
|
# Check the Protos category
|
|
336
|
-
if self.category == 'protos' and self.
|
|
343
|
+
if self.category == 'protos' and self.category_type not in Snapend.CATEGORY_TYPE_PROTOS:
|
|
337
344
|
snapctl_error(
|
|
338
|
-
message="Invalid Protos
|
|
339
|
-
f"{', '.join(Snapend.
|
|
345
|
+
message="Invalid Protos Type. Valid type are " +
|
|
346
|
+
f"{', '.join(Snapend.CATEGORY_TYPE_PROTOS)}.",
|
|
340
347
|
code=SNAPCTL_INPUT_ERROR
|
|
341
348
|
)
|
|
342
349
|
# Check the auth type
|
|
343
350
|
if self.category == 'sdk':
|
|
344
|
-
if not self.
|
|
351
|
+
if not self.category_type:
|
|
345
352
|
snapctl_error(
|
|
346
|
-
message="Missing required parameter:
|
|
353
|
+
message="Missing required parameter: --type",
|
|
347
354
|
code=SNAPCTL_INPUT_ERROR)
|
|
348
|
-
if self.
|
|
355
|
+
if self.category_type not in Snapend.CATEGORY_TYPE_SDK:
|
|
349
356
|
snapctl_error(
|
|
350
|
-
message="Invalid
|
|
351
|
-
f"{', '.join(Snapend.
|
|
357
|
+
message="Invalid SDK Type. Valid type are " +
|
|
358
|
+
f"{', '.join(Snapend.CATEGORY_TYPE_SDK)}.",
|
|
352
359
|
code=SNAPCTL_INPUT_ERROR
|
|
353
360
|
)
|
|
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
361
|
# Special cases for client SDKs
|
|
366
|
-
if self.
|
|
367
|
-
if self.
|
|
362
|
+
if self.category_format in CLIENT_SDK_TYPES:
|
|
363
|
+
if self.category_type in ['server', 'app']:
|
|
368
364
|
snapctl_error(
|
|
369
|
-
message="Invalid combination of
|
|
365
|
+
message="Invalid combination of format and type. " +
|
|
370
366
|
", ".join(CLIENT_SDK_TYPES.keys()) +
|
|
371
|
-
" SDKs are only available for
|
|
367
|
+
" SDKs are only available for --type=user",
|
|
372
368
|
code=SNAPCTL_INPUT_ERROR
|
|
373
369
|
)
|
|
374
|
-
if self.
|
|
370
|
+
if self.category_type == 'internal':
|
|
375
371
|
snapctl_error(
|
|
376
372
|
message="Internal access type is not supported for " +
|
|
377
373
|
", ".join(CLIENT_SDK_TYPES.keys()) + " SDKs.",
|
|
@@ -458,7 +454,7 @@ class Snapend:
|
|
|
458
454
|
progress.add_task(
|
|
459
455
|
description='Cloning your snapend from the manifest...', total=None)
|
|
460
456
|
try:
|
|
461
|
-
with open(self.
|
|
457
|
+
with open(self.manifest_path_filename, 'rb') as file:
|
|
462
458
|
files = {'snapend-manifest': file}
|
|
463
459
|
payload = {
|
|
464
460
|
'game_id': self.game_id,
|
|
@@ -482,9 +478,13 @@ class Snapend:
|
|
|
482
478
|
progress=progress
|
|
483
479
|
)
|
|
484
480
|
self._assign_snapend_id(response['cluster']['id'])
|
|
485
|
-
info(
|
|
486
|
-
f"Cluster ID assigned: {response['cluster']['id']}")
|
|
481
|
+
info(f"Cluster ID assigned: {response['cluster']['id']}")
|
|
487
482
|
if self.blocking:
|
|
483
|
+
snapctl_success(
|
|
484
|
+
message='Snapend clone initiated.',
|
|
485
|
+
progress=progress,
|
|
486
|
+
no_exit=True
|
|
487
|
+
)
|
|
488
488
|
status = self._blocking_get_status()
|
|
489
489
|
# Fetch the new manifest
|
|
490
490
|
if status is True:
|
|
@@ -532,7 +532,7 @@ class Snapend:
|
|
|
532
532
|
progress.add_task(
|
|
533
533
|
description='Applying your manifest...', total=None)
|
|
534
534
|
try:
|
|
535
|
-
with open(self.
|
|
535
|
+
with open(self.manifest_path_filename, 'rb') as file:
|
|
536
536
|
files = {'snapend-manifest': file}
|
|
537
537
|
payload = {
|
|
538
538
|
'ext': self.manifest_file_name.split('.')[-1]
|
|
@@ -554,6 +554,11 @@ class Snapend:
|
|
|
554
554
|
)
|
|
555
555
|
self._assign_snapend_id(response['cluster']['id'])
|
|
556
556
|
if self.blocking:
|
|
557
|
+
snapctl_success(
|
|
558
|
+
message='Snapend apply has been initiated.',
|
|
559
|
+
progress=progress,
|
|
560
|
+
no_exit=True
|
|
561
|
+
)
|
|
557
562
|
status = self._blocking_get_status()
|
|
558
563
|
# Fetch the new manifest
|
|
559
564
|
if status is True:
|
|
@@ -600,7 +605,7 @@ class Snapend:
|
|
|
600
605
|
progress.add_task(
|
|
601
606
|
description='Promoting your staging snapend...', total=None)
|
|
602
607
|
try:
|
|
603
|
-
with open(self.
|
|
608
|
+
with open(self.manifest_path_filename, 'rb') as file:
|
|
604
609
|
payload = {
|
|
605
610
|
'snapend_id': self.snapend_id
|
|
606
611
|
}
|
|
@@ -621,6 +626,11 @@ class Snapend:
|
|
|
621
626
|
)
|
|
622
627
|
self._assign_snapend_id(response['cluster']['id'])
|
|
623
628
|
if self.blocking:
|
|
629
|
+
snapctl_success(
|
|
630
|
+
message='Snapend promotion has been initiated.',
|
|
631
|
+
progress=progress,
|
|
632
|
+
no_exit=True
|
|
633
|
+
)
|
|
624
634
|
status = self._blocking_get_status()
|
|
625
635
|
if status is True:
|
|
626
636
|
# TODO: Uncomment this if we want to do an auto download
|
|
@@ -715,6 +725,11 @@ class Snapend:
|
|
|
715
725
|
)
|
|
716
726
|
if res.ok:
|
|
717
727
|
if self.blocking:
|
|
728
|
+
snapctl_success(
|
|
729
|
+
message='Snapend update has been initiated.',
|
|
730
|
+
progress=progress,
|
|
731
|
+
no_exit=True
|
|
732
|
+
)
|
|
718
733
|
status = self._blocking_get_status()
|
|
719
734
|
# Fetch the new manifest
|
|
720
735
|
if status is True:
|
snapctl/config/constants.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
Constants used by snapctl
|
|
3
3
|
"""
|
|
4
4
|
COMPANY_NAME = 'Snapser'
|
|
5
|
-
|
|
5
|
+
VERSION_PREFIX = 'beta-'
|
|
6
|
+
VERSION = '0.46.0'
|
|
6
7
|
CONFIG_FILE_MAC = '~/.snapser/config'
|
|
7
8
|
CONFIG_FILE_WIN = '%homepath%\\.snapser\\config'
|
|
8
9
|
|
|
@@ -33,12 +34,12 @@ SNAPCTL_ERROR = 1
|
|
|
33
34
|
SNAPCTL_INPUT_ERROR = 2
|
|
34
35
|
SNAPCTL_RESOURCE_NOT_FOUND = 3
|
|
35
36
|
|
|
36
|
-
# Configuration Errors
|
|
37
|
+
# Configuration Errors - 10 - 19
|
|
37
38
|
SNAPCTL_CONFIGURATION_INCORRECT = 10
|
|
38
39
|
SNAPCTL_CONFIGURATION_ERROR = 11
|
|
39
40
|
SNAPCTL_DEPENDENCY_MISSING = 12
|
|
40
41
|
|
|
41
|
-
# BYOGS Errors
|
|
42
|
+
# BYOGS Errors - 20 - 29
|
|
42
43
|
SNAPCTL_BYOGS_GENERIC_ERROR = 20
|
|
43
44
|
SNAPCTL_BYOGS_DEPENDENCY_MISSING = 21
|
|
44
45
|
SNAPCTL_BYOGS_ECR_LOGIN_ERROR = 22
|
|
@@ -48,7 +49,7 @@ SNAPCTL_BYOGS_PUBLISH_ERROR = 25
|
|
|
48
49
|
SNAPCTL_BYOGS_PUBLISH_PERMISSION_ERROR = 26
|
|
49
50
|
SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR = 27
|
|
50
51
|
|
|
51
|
-
# BYOSNAP Errors
|
|
52
|
+
# BYOSNAP Errors - 30 - 49 then 86 - 99
|
|
52
53
|
SNAPCTL_BYOSNAP_NOT_FOUND = SNAPCTL_RESOURCE_NOT_FOUND
|
|
53
54
|
SNAPCTL_BYOSNAP_GENERIC_ERROR = 30
|
|
54
55
|
SNAPCTL_BYOSNAP_DEPENDENCY_MISSING = 31
|
|
@@ -70,8 +71,10 @@ SNAPCTL_BYOSNAP_UPDATE_VERSION_SERVICE_IN_USE_ERROR = 46
|
|
|
70
71
|
SNAPCTL_BYOSNAP_UPDATE_VERSION_TAG_ERROR = 47
|
|
71
72
|
SNAPCTL_BYOSNAP_UPDATE_VERSION_INVALID_VERSION_ERROR = 48
|
|
72
73
|
SNAPCTL_BYOSNAP_PUBLISH_ERROR = 49
|
|
74
|
+
# Starting with new error codes for BYOSNAP post
|
|
75
|
+
SNAPCTL_BYOSNAP_GENERATE_PROFILE_ERROR = 86
|
|
73
76
|
|
|
74
|
-
# Game Errors
|
|
77
|
+
# Game Errors - 50 - 60
|
|
75
78
|
SNAPCTL_GAME_NOT_FOUND = SNAPCTL_RESOURCE_NOT_FOUND
|
|
76
79
|
SNAPCTL_GAME_GENERIC_ERROR = 50
|
|
77
80
|
SNAPCTL_GAME_CREATE_ERROR = 51
|
|
@@ -80,7 +83,7 @@ SNAPCTL_GAME_CREATE_LIMIT_ERROR = 53
|
|
|
80
83
|
SNAPCTL_GAME_CREATE_DUPLICATE_NAME_ERROR = 54
|
|
81
84
|
SNAPCTL_GAME_ENUMERATE_ERROR = 55
|
|
82
85
|
|
|
83
|
-
# Snapend Errors
|
|
86
|
+
# Snapend Errors - 60 - 79
|
|
84
87
|
SNAPCTL_SNAPEND_NOT_FOUND = SNAPCTL_RESOURCE_NOT_FOUND
|
|
85
88
|
SNAPCTL_SNAPEND_GENERIC_ERROR = 60
|
|
86
89
|
SNAPCTL_SNAPEND_ENUMERATE_ERROR = 61
|
|
@@ -99,7 +102,6 @@ SNAPCTL_SNAPEND_UPDATE_SERVER_ERROR = 73
|
|
|
99
102
|
SNAPCTL_SNAPEND_UPDATE_TIMEOUT_ERROR = 74
|
|
100
103
|
SNAPCTL_SNAPEND_STATE_ERROR = 75
|
|
101
104
|
|
|
102
|
-
# Generate Errors
|
|
105
|
+
# Generate Errors - 80 - 85
|
|
103
106
|
SNAPCTL_GENERATE_GENERIC_ERROR = 80
|
|
104
|
-
|
|
105
|
-
SNAPCTL_GENERATE_CREDENTIALS_ERROR = 82
|
|
107
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR = 81
|
snapctl/config/hashes.py
CHANGED
|
@@ -160,6 +160,24 @@ SERVICE_IDS: List[str] = [
|
|
|
160
160
|
'trackables', 'xp'
|
|
161
161
|
]
|
|
162
162
|
|
|
163
|
+
SDK_ACCESS_AUTH_TYPE_LOOKUP: Dict[str, Dict[str, str]] = {
|
|
164
|
+
'user': {
|
|
165
|
+
'access_type': 'external',
|
|
166
|
+
'auth_type': 'user'
|
|
167
|
+
},
|
|
168
|
+
'server': {
|
|
169
|
+
'access_type': 'external',
|
|
170
|
+
'auth_type': 'api-key'
|
|
171
|
+
},
|
|
172
|
+
'internal': {
|
|
173
|
+
'access_type': 'internal',
|
|
174
|
+
},
|
|
175
|
+
'app': {
|
|
176
|
+
'access_type': 'external',
|
|
177
|
+
'auth_type': 'app'
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
|
|
163
181
|
DEFAULT_BYOSNAP_DEV_TEMPLATE: Dict[str, object] = {
|
|
164
182
|
'cpu': 100,
|
|
165
183
|
'memory': 0.125,
|
|
@@ -187,31 +205,6 @@ DEFAULT_BYOSNAP_PROD_TEMPLATE: Dict[str, object] = {
|
|
|
187
205
|
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "PRODUCTION"}]
|
|
188
206
|
}
|
|
189
207
|
|
|
190
|
-
BYOSNAP_TEMPLATE: Dict[str, Dict[str, object]] = {
|
|
191
|
-
'name': "TODO: Add your BYOSnap name here. Name has to start with byosnap-. This is to ensure we avoid any collisions.",
|
|
192
|
-
'description': "TODO: Add your BYOSnap description here",
|
|
193
|
-
'platform': "TODO: Add your platform here. Options are 'linux/arm64' or 'linux/amd64'",
|
|
194
|
-
'language': "TODO: Add your language here. Options are 'go', 'node', 'python', 'java', 'csharp', 'cpp', 'rust', 'ruby', 'php', 'perl', 'clojure', 'lua', 'ts', 'js', 'kotlin', 'c'",
|
|
195
|
-
'prefix': "TODO: Add your prefix here. Prefix should start with /. Eg: '/v1'",
|
|
196
|
-
'ingress': {
|
|
197
|
-
'external_port': {
|
|
198
|
-
'name': 'http',
|
|
199
|
-
'port': "TODO: Enter your external port here. Eg: 5003. Make sure it is a number and not a string."
|
|
200
|
-
},
|
|
201
|
-
'internal_ports': [{
|
|
202
|
-
'name': 'TODO: Optionally add your internal port name here. Eg: grpc. Names should be unique across the `ingress` dict. IMPORTANT: If you are not adding any internal ports, just keep `internal_ports: []`",',
|
|
203
|
-
'port': "TODO: Optionally add your internal port here. Eg: 5004. Make sure it is a number and not a string. Port numbers should be unique across the `ingress` dict."
|
|
204
|
-
}]
|
|
205
|
-
},
|
|
206
|
-
'readiness_probe_config': {
|
|
207
|
-
'initial_delay_seconds': "TODO: Optionally add your readiness delay in seconds here. Eg: 5 or use null. Make sure it is a number and not a string.",
|
|
208
|
-
'path': "TODO: Optionally add your readiness path here. Eg: '/health' or use null",
|
|
209
|
-
},
|
|
210
|
-
'dev_template': DEFAULT_BYOSNAP_DEV_TEMPLATE,
|
|
211
|
-
'stage_template': DEFAULT_BYOSNAP_STAGE_TEMPLATE,
|
|
212
|
-
'prod_template': DEFAULT_BYOSNAP_PROD_TEMPLATE
|
|
213
|
-
}
|
|
214
|
-
|
|
215
208
|
ARCHITECTURE_MAPPING: Dict[str, str] = {
|
|
216
209
|
'x86_64': 'amd64',
|
|
217
210
|
'arm64': 'arm64',
|