snapctl 0.32.2__py3-none-any.whl → 0.35.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 +14 -10
- snapctl/commands/byosnap.py +17 -11
- snapctl/commands/generate.py +135 -13
- snapctl/config/constants.py +3 -2
- snapctl/config/hashes.py +21 -5
- snapctl/main.py +35 -11
- {snapctl-0.32.2.dist-info → snapctl-0.35.0.dist-info}/METADATA +18 -5
- {snapctl-0.32.2.dist-info → snapctl-0.35.0.dist-info}/RECORD +11 -11
- {snapctl-0.32.2.dist-info → snapctl-0.35.0.dist-info}/WHEEL +1 -1
- {snapctl-0.32.2.dist-info → snapctl-0.35.0.dist-info}/LICENSE +0 -0
- {snapctl-0.32.2.dist-info → snapctl-0.35.0.dist-info}/entry_points.txt +0 -0
snapctl/commands/byogs.py
CHANGED
|
@@ -8,14 +8,13 @@ import subprocess
|
|
|
8
8
|
from sys import platform
|
|
9
9
|
from typing import Union
|
|
10
10
|
|
|
11
|
-
import typer
|
|
12
11
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
13
12
|
from snapctl.config.constants import SNAPCTL_BYOGS_DEPENDENCY_MISSING, \
|
|
14
13
|
SNAPCTL_BYOGS_ECR_LOGIN_ERROR, SNAPCTL_BYOGS_BUILD_ERROR, \
|
|
15
14
|
SNAPCTL_BYOGS_TAG_ERROR, SNAPCTL_BYOGS_PUBLISH_ERROR, \
|
|
16
15
|
SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR, SNAPCTL_INPUT_ERROR
|
|
17
|
-
from snapctl.utils.echo import error, success
|
|
18
16
|
from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
|
|
17
|
+
from snapctl.utils.echo import info
|
|
19
18
|
|
|
20
19
|
|
|
21
20
|
class ByoGs:
|
|
@@ -33,6 +32,7 @@ class ByoGs:
|
|
|
33
32
|
def __init__(
|
|
34
33
|
self, subcommand: str, base_url: str, api_key: str | None,
|
|
35
34
|
input_tag: Union[str, None], path: Union[str, None], dockerfile: str,
|
|
35
|
+
skip_build: bool = False
|
|
36
36
|
) -> None:
|
|
37
37
|
self.subcommand: str = subcommand
|
|
38
38
|
self.base_url: str = base_url
|
|
@@ -49,6 +49,7 @@ class ByoGs:
|
|
|
49
49
|
self.input_tag: Union[str, None] = input_tag
|
|
50
50
|
self.path: Union[str, None] = path
|
|
51
51
|
self.dockerfile: str = dockerfile
|
|
52
|
+
self.skip_build: bool = skip_build
|
|
52
53
|
# Validate input
|
|
53
54
|
self.validate_input()
|
|
54
55
|
|
|
@@ -143,7 +144,7 @@ class ByoGs:
|
|
|
143
144
|
progress.add_task(
|
|
144
145
|
description='Building your snap...', total=None)
|
|
145
146
|
try:
|
|
146
|
-
image_tag = f'{ByoGs.SID}.{self.input_tag}'
|
|
147
|
+
# image_tag = f'{ByoGs.SID}.{self.input_tag}'
|
|
147
148
|
build_platform = ByoGs.DEFAULT_BUILD_PLATFORM
|
|
148
149
|
if len(self.token_parts) == 4:
|
|
149
150
|
build_platform = self.token_parts[3]
|
|
@@ -152,14 +153,14 @@ class ByoGs:
|
|
|
152
153
|
if platform == "win32":
|
|
153
154
|
response = subprocess.run([
|
|
154
155
|
# f"docker build --no-cache -t {tag} {path}"
|
|
155
|
-
'docker', 'build', '--platform', build_platform, '-t',
|
|
156
|
+
'docker', 'build', '--platform', build_platform, '-t', self.input_tag,
|
|
156
157
|
'-f', docker_file_path, self.path
|
|
157
158
|
], shell=True, check=False)
|
|
158
159
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
159
160
|
else:
|
|
160
161
|
response = subprocess.run([
|
|
161
162
|
# f"docker build --no-cache -t {tag} {path}"
|
|
162
|
-
f"docker build --platform {build_platform} -t {
|
|
163
|
+
f"docker build --platform {build_platform} -t {self.input_tag} "
|
|
163
164
|
f"-f {docker_file_path} {self.path}"
|
|
164
165
|
], shell=True, check=False)
|
|
165
166
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
@@ -188,11 +189,11 @@ class ByoGs:
|
|
|
188
189
|
# Tag the repo
|
|
189
190
|
if platform == "win32":
|
|
190
191
|
response = subprocess.run([
|
|
191
|
-
'docker', 'tag',
|
|
192
|
+
'docker', 'tag', self.input_tag, full_ecr_repo_url
|
|
192
193
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
193
194
|
else:
|
|
194
195
|
response = subprocess.run([
|
|
195
|
-
f"docker tag {
|
|
196
|
+
f"docker tag {self.input_tag} {full_ecr_repo_url}"
|
|
196
197
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
197
198
|
if not response.returncode:
|
|
198
199
|
return snapctl_success('BYOGS tag successful', progress, no_exit=True)
|
|
@@ -263,11 +264,11 @@ class ByoGs:
|
|
|
263
264
|
SNAPCTL_INPUT_ERROR
|
|
264
265
|
)
|
|
265
266
|
if self.subcommand in ['build', 'publish']:
|
|
266
|
-
if not self.path:
|
|
267
|
+
if not self.skip_build and not self.path:
|
|
267
268
|
snapctl_error("Missing required parameter: path",
|
|
268
269
|
SNAPCTL_INPUT_ERROR)
|
|
269
270
|
# Check path
|
|
270
|
-
if not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
271
|
+
if not self.skip_build and not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
271
272
|
snapctl_error(
|
|
272
273
|
f"Unable to find {self.dockerfile} at path {self.path}", SNAPCTL_INPUT_ERROR)
|
|
273
274
|
# elif self.subcommand == 'push':
|
|
@@ -313,7 +314,10 @@ class ByoGs:
|
|
|
313
314
|
"""
|
|
314
315
|
self._check_dependencies()
|
|
315
316
|
self._docker_login()
|
|
316
|
-
self.
|
|
317
|
+
if not self.skip_build:
|
|
318
|
+
self._docker_build()
|
|
319
|
+
else:
|
|
320
|
+
info('--skip-build set. Skipping the build step.')
|
|
317
321
|
self._docker_tag()
|
|
318
322
|
self._docker_push()
|
|
319
323
|
snapctl_success('BYOGS publish successful')
|
snapctl/commands/byosnap.py
CHANGED
|
@@ -46,7 +46,8 @@ class ByoSnap:
|
|
|
46
46
|
self, subcommand: str, base_url: str, api_key: str | None, sid: str, name: str,
|
|
47
47
|
desc: str, platform_type: str, language: str, input_tag: Union[str, None],
|
|
48
48
|
path: Union[str, None], dockerfile: str, prefix: str, version: Union[str, None],
|
|
49
|
-
http_port: Union[int, None], byosnap_profile: Union[str, None]
|
|
49
|
+
http_port: Union[int, None], byosnap_profile: Union[str, None],
|
|
50
|
+
skip_build: bool = False
|
|
50
51
|
) -> None:
|
|
51
52
|
self.subcommand: str = subcommand
|
|
52
53
|
self.base_url: str = base_url
|
|
@@ -72,6 +73,7 @@ class ByoSnap:
|
|
|
72
73
|
self.version: Union[str, None] = version
|
|
73
74
|
self.http_port: Union[int, None] = http_port
|
|
74
75
|
self.byosnap_profile: Union[str, None] = byosnap_profile
|
|
76
|
+
self.skip_build: bool = skip_build
|
|
75
77
|
# Validate the input
|
|
76
78
|
self.validate_input()
|
|
77
79
|
|
|
@@ -162,7 +164,7 @@ class ByoSnap:
|
|
|
162
164
|
|
|
163
165
|
def _docker_build(self) -> None:
|
|
164
166
|
# Get the data
|
|
165
|
-
image_tag = f'{self.sid}.{self.input_tag}'
|
|
167
|
+
# image_tag = f'{self.sid}.{self.input_tag}'
|
|
166
168
|
build_platform = ByoSnap.DEFAULT_BUILD_PLATFORM
|
|
167
169
|
if len(self.token_parts) == 4:
|
|
168
170
|
build_platform = self.token_parts[3]
|
|
@@ -180,14 +182,14 @@ class ByoSnap:
|
|
|
180
182
|
if platform == "win32":
|
|
181
183
|
response = subprocess.run([
|
|
182
184
|
# f"docker build --no-cache -t {tag} {path}"
|
|
183
|
-
'docker', 'build', '--platform', build_platform, '-t',
|
|
185
|
+
'docker', 'build', '--platform', build_platform, '-t', self.input_tag,
|
|
184
186
|
'-f', docker_file_path, self.path
|
|
185
187
|
], shell=True, check=False)
|
|
186
188
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
187
189
|
else:
|
|
188
190
|
response = subprocess.run([
|
|
189
191
|
# f"docker build --no-cache -t {tag} {path}"
|
|
190
|
-
f"docker build --platform {build_platform} -t {
|
|
192
|
+
f"docker build --platform {build_platform} -t {self.input_tag} "
|
|
191
193
|
f"-f {docker_file_path} {self.path}"
|
|
192
194
|
], shell=True, check=False)
|
|
193
195
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
@@ -217,11 +219,11 @@ class ByoSnap:
|
|
|
217
219
|
# Tag the repo
|
|
218
220
|
if platform == "win32":
|
|
219
221
|
response = subprocess.run([
|
|
220
|
-
'docker', 'tag',
|
|
222
|
+
'docker', 'tag', self.input_tag, full_ecr_repo_url
|
|
221
223
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
222
224
|
else:
|
|
223
225
|
response = subprocess.run([
|
|
224
|
-
f"docker tag {
|
|
226
|
+
f"docker tag {self.input_tag} {full_ecr_repo_url}"
|
|
225
227
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
226
228
|
if not response.returncode:
|
|
227
229
|
return snapctl_success('BYOSnap tag successful',
|
|
@@ -372,7 +374,7 @@ class ByoSnap:
|
|
|
372
374
|
if self.token_parts is None:
|
|
373
375
|
snapctl_error('Invalid token. Please reach out to your support team.',
|
|
374
376
|
SNAPCTL_INPUT_ERROR)
|
|
375
|
-
if self.subcommand in ['
|
|
377
|
+
if self.subcommand in ['publish-image']:
|
|
376
378
|
if not self.input_tag:
|
|
377
379
|
snapctl_error(
|
|
378
380
|
"Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
|
|
@@ -383,11 +385,11 @@ class ByoSnap:
|
|
|
383
385
|
f"{ByoSnap.TAG_CHARACTER_LIMIT} characters",
|
|
384
386
|
SNAPCTL_INPUT_ERROR
|
|
385
387
|
)
|
|
386
|
-
if not self.path:
|
|
388
|
+
if not self.skip_build and not self.path:
|
|
387
389
|
snapctl_error("Missing required parameter: path",
|
|
388
390
|
SNAPCTL_INPUT_ERROR)
|
|
389
391
|
# Check path
|
|
390
|
-
if not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
392
|
+
if not self.skip_build and not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
391
393
|
snapctl_error(
|
|
392
394
|
f"Unable to find {self.dockerfile} at path {self.path}",
|
|
393
395
|
SNAPCTL_INPUT_ERROR)
|
|
@@ -592,10 +594,14 @@ class ByoSnap:
|
|
|
592
594
|
"""
|
|
593
595
|
self._check_dependencies()
|
|
594
596
|
self._docker_login()
|
|
595
|
-
self.
|
|
597
|
+
if not self.skip_build:
|
|
598
|
+
self._docker_build()
|
|
599
|
+
else:
|
|
600
|
+
info('--skip-build set. Skipping the build step.')
|
|
596
601
|
self._docker_tag()
|
|
597
602
|
self._docker_push()
|
|
598
|
-
self.
|
|
603
|
+
if self.path is not None:
|
|
604
|
+
self.upload_docs()
|
|
599
605
|
snapctl_success('BYOSNAP publish successful')
|
|
600
606
|
|
|
601
607
|
def publish_version(self) -> None:
|
snapctl/commands/generate.py
CHANGED
|
@@ -1,35 +1,60 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Generate CLI commands
|
|
3
3
|
"""
|
|
4
|
+
import base64
|
|
5
|
+
from binascii import Error as BinasciiError
|
|
4
6
|
import json
|
|
5
7
|
import os
|
|
6
8
|
from typing import Union
|
|
7
9
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
8
10
|
from snapctl.config.constants import SNAPCTL_INPUT_ERROR, \
|
|
9
|
-
SNAPCTL_GENERATE_GENERIC_ERROR
|
|
11
|
+
SNAPCTL_GENERATE_GENERIC_ERROR, SNAPCTL_GENERATE_PROFILE_ERROR, \
|
|
12
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR
|
|
10
13
|
from snapctl.config.hashes import BYOSNAP_TEMPLATE
|
|
11
|
-
from snapctl.utils.
|
|
12
|
-
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
14
|
+
from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class Generate:
|
|
16
18
|
"""
|
|
17
19
|
Generate CLI commands
|
|
18
20
|
"""
|
|
19
|
-
SUBCOMMANDS = ['byosnap-profile']
|
|
21
|
+
SUBCOMMANDS = ['byosnap-profile', 'profile', 'credentials']
|
|
22
|
+
DEPRECATED_SOON_SUBCOMMANDS = ['byosnap-profile']
|
|
20
23
|
BYOSNAP_PROFILE_FN = 'snapser-byosnap-profile.json'
|
|
24
|
+
ECR_TOKEN_FN = 'snapser-ecr-credentials.json'
|
|
25
|
+
CATEGORIES = {
|
|
26
|
+
'profile': ['byosnap'],
|
|
27
|
+
'credentials': ['ecr']
|
|
28
|
+
}
|
|
21
29
|
|
|
22
30
|
def __init__(
|
|
23
31
|
self, subcommand: str, base_url: str, api_key: str | None,
|
|
32
|
+
category: str | None,
|
|
24
33
|
out_path: Union[str, None]
|
|
25
34
|
) -> None:
|
|
26
35
|
self.subcommand: str = subcommand
|
|
27
36
|
self.base_url: str = base_url
|
|
28
37
|
self.api_key: str = api_key
|
|
38
|
+
self.category: str | None = category
|
|
29
39
|
self.out_path: Union[str, None] = out_path
|
|
30
40
|
# Validate input
|
|
31
41
|
self.validate_input()
|
|
32
42
|
|
|
43
|
+
# Private methods
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _get_token_values(token: str) -> None | list:
|
|
46
|
+
"""
|
|
47
|
+
Get the token values
|
|
48
|
+
"""
|
|
49
|
+
try:
|
|
50
|
+
input_token = base64.b64decode(token).decode('ascii')
|
|
51
|
+
token_parts = input_token.split('|')
|
|
52
|
+
# url|web_app_token|service_id|ecr_repo_url|ecr_repo_username|ecr_repo_token
|
|
53
|
+
if len(token_parts) >= 3:
|
|
54
|
+
return token_parts
|
|
55
|
+
except BinasciiError:
|
|
56
|
+
pass
|
|
57
|
+
return None
|
|
33
58
|
# Validator
|
|
34
59
|
|
|
35
60
|
def validate_input(self) -> None:
|
|
@@ -42,14 +67,38 @@ class Generate:
|
|
|
42
67
|
f"{Generate.SUBCOMMANDS}",
|
|
43
68
|
SNAPCTL_INPUT_ERROR
|
|
44
69
|
)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if self.
|
|
70
|
+
# Check path
|
|
71
|
+
if self.subcommand == 'profile':
|
|
72
|
+
if self.category not in Generate.CATEGORIES['profile']:
|
|
73
|
+
snapctl_error(
|
|
74
|
+
f"Invalid category {self.category}. Valid category are "
|
|
75
|
+
f"{Generate.CATEGORIES['profile']}",
|
|
76
|
+
SNAPCTL_INPUT_ERROR
|
|
77
|
+
)
|
|
78
|
+
if not self.out_path:
|
|
79
|
+
snapctl_error(
|
|
80
|
+
"Path is required for profile generation",
|
|
81
|
+
SNAPCTL_INPUT_ERROR
|
|
82
|
+
)
|
|
83
|
+
elif self.subcommand == 'credentials':
|
|
84
|
+
if self.category not in Generate.CATEGORIES['credentials']:
|
|
48
85
|
snapctl_error(
|
|
49
|
-
f"Invalid
|
|
50
|
-
"
|
|
86
|
+
f"Invalid category {self.category}. Valid category are "
|
|
87
|
+
f"{Generate.CATEGORIES['credentials']}",
|
|
51
88
|
SNAPCTL_INPUT_ERROR
|
|
52
89
|
)
|
|
90
|
+
if not self.out_path:
|
|
91
|
+
snapctl_error(
|
|
92
|
+
"Path is required for token generation",
|
|
93
|
+
SNAPCTL_INPUT_ERROR
|
|
94
|
+
)
|
|
95
|
+
# Now confirm that out-path is valid
|
|
96
|
+
if self.out_path and not os.path.isdir(self.out_path):
|
|
97
|
+
snapctl_error(
|
|
98
|
+
f"Invalid path {self.out_path}. Wont be able to "
|
|
99
|
+
"store the output file",
|
|
100
|
+
SNAPCTL_INPUT_ERROR
|
|
101
|
+
)
|
|
53
102
|
|
|
54
103
|
def byosnap_profile(self) -> None:
|
|
55
104
|
"""
|
|
@@ -62,7 +111,7 @@ class Generate:
|
|
|
62
111
|
)
|
|
63
112
|
progress.start()
|
|
64
113
|
progress.add_task(
|
|
65
|
-
description='
|
|
114
|
+
description='Generating BYOSnap profile...', total=None)
|
|
66
115
|
try:
|
|
67
116
|
if self.out_path is not None:
|
|
68
117
|
file_save_path = os.path.join(
|
|
@@ -82,12 +131,85 @@ class Generate:
|
|
|
82
131
|
)
|
|
83
132
|
except (IOError, OSError) as file_error:
|
|
84
133
|
snapctl_error(f"File error: {file_error}",
|
|
85
|
-
|
|
134
|
+
SNAPCTL_GENERATE_PROFILE_ERROR, progress)
|
|
86
135
|
except json.JSONDecodeError as json_error:
|
|
87
136
|
snapctl_error(f"JSON error: {json_error}",
|
|
88
|
-
|
|
137
|
+
SNAPCTL_GENERATE_PROFILE_ERROR, progress)
|
|
89
138
|
snapctl_error(
|
|
90
139
|
"Failed to generate BYOSNAP Profile",
|
|
91
|
-
|
|
140
|
+
SNAPCTL_GENERATE_PROFILE_ERROR,
|
|
92
141
|
progress
|
|
93
142
|
)
|
|
143
|
+
|
|
144
|
+
def profile(self) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Generate profile
|
|
147
|
+
"""
|
|
148
|
+
if self.category == 'byosnap':
|
|
149
|
+
self.byosnap_profile()
|
|
150
|
+
|
|
151
|
+
def ecr_credentials(self) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Generate credentials
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
progress = Progress(
|
|
157
|
+
SpinnerColumn(),
|
|
158
|
+
TextColumn("[progress.description]{task.description}"),
|
|
159
|
+
transient=True,
|
|
160
|
+
)
|
|
161
|
+
progress.start()
|
|
162
|
+
progress.add_task(
|
|
163
|
+
description='Generating ECR credentials...', total=None)
|
|
164
|
+
try:
|
|
165
|
+
composite_token: Union[str, None] = get_composite_token(
|
|
166
|
+
self.base_url, self.api_key, 'byogs', {'service_id': 'byogs'}
|
|
167
|
+
)
|
|
168
|
+
token_parts = Generate._get_token_values(composite_token)
|
|
169
|
+
# url|web_app_token|service_id|ecr_repo_url|ecr_repo_username|ecr_repo_token
|
|
170
|
+
if token_parts is None or len(token_parts) != 4:
|
|
171
|
+
snapctl_error(
|
|
172
|
+
"Unable to retrieve token.",
|
|
173
|
+
SNAPCTL_GENERATE_GENERIC_ERROR,
|
|
174
|
+
progress
|
|
175
|
+
)
|
|
176
|
+
token_details = {
|
|
177
|
+
'ecr_repo_url': token_parts[0],
|
|
178
|
+
'ecr_repo_username': token_parts[1],
|
|
179
|
+
'ecr_repo_token': token_parts[2],
|
|
180
|
+
'ecr_repo_platform': token_parts[3]
|
|
181
|
+
}
|
|
182
|
+
if self.out_path is not None:
|
|
183
|
+
file_save_path = os.path.join(
|
|
184
|
+
self.out_path, Generate.ECR_TOKEN_FN)
|
|
185
|
+
else:
|
|
186
|
+
file_save_path = os.path.join(
|
|
187
|
+
os.getcwd(), Generate.ECR_TOKEN_FN)
|
|
188
|
+
file_written = False
|
|
189
|
+
with open(file_save_path, "w") as file:
|
|
190
|
+
json.dump(token_details, file, indent=4)
|
|
191
|
+
file_written = True
|
|
192
|
+
if file_written:
|
|
193
|
+
snapctl_success(
|
|
194
|
+
"ECR Token generation successful. "
|
|
195
|
+
f"{Generate.ECR_TOKEN_FN} saved at {file_save_path}",
|
|
196
|
+
progress
|
|
197
|
+
)
|
|
198
|
+
except (IOError, OSError) as file_error:
|
|
199
|
+
snapctl_error(f"File error: {file_error}",
|
|
200
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR, progress)
|
|
201
|
+
except json.JSONDecodeError as json_error:
|
|
202
|
+
snapctl_error(f"JSON error: {json_error}",
|
|
203
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR, progress)
|
|
204
|
+
snapctl_error(
|
|
205
|
+
"Failed to generate Token",
|
|
206
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR,
|
|
207
|
+
progress
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
def credentials(self):
|
|
211
|
+
"""
|
|
212
|
+
Generate credentials
|
|
213
|
+
"""
|
|
214
|
+
if self.category == 'ecr':
|
|
215
|
+
self.ecr_credentials()
|
snapctl/config/constants.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Constants used by snapctl
|
|
3
3
|
"""
|
|
4
4
|
COMPANY_NAME = 'Snapser'
|
|
5
|
-
VERSION = '0.
|
|
5
|
+
VERSION = '0.35.0'
|
|
6
6
|
CONFIG_FILE_MAC = '~/.snapser/config'
|
|
7
7
|
CONFIG_FILE_WIN = '%homepath%\\.snapser\\config'
|
|
8
8
|
|
|
@@ -88,4 +88,5 @@ SNAPCTL_SNAPEND_STATE_ERROR = 75
|
|
|
88
88
|
|
|
89
89
|
# Generate Errors
|
|
90
90
|
SNAPCTL_GENERATE_GENERIC_ERROR = 80
|
|
91
|
-
|
|
91
|
+
SNAPCTL_GENERATE_PROFILE_ERROR = 81
|
|
92
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR = 82
|
snapctl/config/hashes.py
CHANGED
|
@@ -156,16 +156,32 @@ SERVICE_IDS = [
|
|
|
156
156
|
'trackables', 'xp'
|
|
157
157
|
]
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
DEFAULT_BYOSNAP_DEV_TEMPLATE = {
|
|
160
160
|
'cpu': 100,
|
|
161
161
|
'memory': 0.125,
|
|
162
162
|
'cmd': '',
|
|
163
163
|
'args': [],
|
|
164
|
-
'env_params': []
|
|
164
|
+
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "DEVELOPMENT"}]
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
DEFAULT_BYOSNAP_STAGE_TEMPLATE = {
|
|
168
|
+
'cpu': 100,
|
|
169
|
+
'memory': 0.125,
|
|
170
|
+
'cmd': '',
|
|
171
|
+
'args': [],
|
|
172
|
+
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "STAGING"}]
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
DEFAULT_BYOSNAP_PROD_TEMPLATE = {
|
|
176
|
+
'cpu': 100,
|
|
177
|
+
'memory': 0.125,
|
|
178
|
+
'cmd': '',
|
|
179
|
+
'args': [],
|
|
180
|
+
'env_params': [{'key': "SNAPSER_ENVIRONMENT", 'value': "PRODUCTION"}]
|
|
165
181
|
}
|
|
166
182
|
|
|
167
183
|
BYOSNAP_TEMPLATE = {
|
|
168
|
-
'dev_template':
|
|
169
|
-
'stage_template':
|
|
170
|
-
'prod_template':
|
|
184
|
+
'dev_template': DEFAULT_BYOSNAP_DEV_TEMPLATE,
|
|
185
|
+
'stage_template': DEFAULT_BYOSNAP_STAGE_TEMPLATE,
|
|
186
|
+
'prod_template': DEFAULT_BYOSNAP_PROD_TEMPLATE
|
|
171
187
|
}
|
snapctl/main.py
CHANGED
|
@@ -203,7 +203,7 @@ def version_callback(value: bool = True):
|
|
|
203
203
|
def common(
|
|
204
204
|
ctx: typer.Context,
|
|
205
205
|
version: bool = typer.Option(
|
|
206
|
-
None, "--version",
|
|
206
|
+
None, "--version", "-v",
|
|
207
207
|
help="Get the Snapctl version.",
|
|
208
208
|
callback=version_callback
|
|
209
209
|
),
|
|
@@ -257,6 +257,9 @@ def byogs(
|
|
|
257
257
|
docker_file: str = typer.Option(
|
|
258
258
|
"Dockerfile", help="Dockerfile name to use"
|
|
259
259
|
),
|
|
260
|
+
skip_build: bool = typer.Option(
|
|
261
|
+
False, "--skip-build", help="(optional: publish) Skip the build step. You have to pass the image tag you used during the build step."
|
|
262
|
+
),
|
|
260
263
|
# overrides
|
|
261
264
|
api_key: Union[str, None] = typer.Option(
|
|
262
265
|
None, "--api-key", help="API Key override.", callback=api_key_context_callback
|
|
@@ -271,7 +274,7 @@ def byogs(
|
|
|
271
274
|
validate_command_context(ctx)
|
|
272
275
|
byogs_obj: ByoGs = ByoGs(
|
|
273
276
|
subcommand, ctx.obj['base_url'], ctx.obj['api_key'],
|
|
274
|
-
tag, path, docker_file,
|
|
277
|
+
tag, path, docker_file, skip_build
|
|
275
278
|
)
|
|
276
279
|
getattr(byogs_obj, subcommand.replace('-', '_'))()
|
|
277
280
|
success(f"BYOGs {subcommand} complete")
|
|
@@ -306,12 +309,12 @@ def byosnap(
|
|
|
306
309
|
# publish-image and publish-version
|
|
307
310
|
tag: str = typer.Option(
|
|
308
311
|
None, "--tag", help=(
|
|
309
|
-
"(req:
|
|
312
|
+
"(req: publish-image and publish-version) Tag for your snap"
|
|
310
313
|
)
|
|
311
314
|
),
|
|
312
315
|
# publish-image
|
|
313
316
|
path: Union[str, None] = typer.Option(
|
|
314
|
-
None, "--path", help="(req:
|
|
317
|
+
None, "--path", help="(req: publish-image) Path to your snap code"
|
|
315
318
|
),
|
|
316
319
|
docker_file: str = typer.Option(
|
|
317
320
|
"Dockerfile", help="Dockerfile name to use"
|
|
@@ -329,9 +332,13 @@ def byosnap(
|
|
|
329
332
|
),
|
|
330
333
|
byosnap_profile: Union[str, None] = typer.Option(
|
|
331
334
|
None, "--byosnap-profile", help=(
|
|
332
|
-
"(req: publish-version) Path to your byosnap-profile JSON file"
|
|
335
|
+
"(req: publish-version) Path to your byosnap-profile JSON file. You can generate a base version of this file using the `snapctl generate profile --category byosnap --out-path <output_path>` command."
|
|
333
336
|
)
|
|
334
337
|
),
|
|
338
|
+
skip_build: bool = typer.Option(
|
|
339
|
+
False, "--skip-build", help="(optional: publish-image) Skip the build step. You have to pass the image tag you used during the build step."
|
|
340
|
+
),
|
|
341
|
+
|
|
335
342
|
# overrides
|
|
336
343
|
api_key: Union[str, None] = typer.Option(
|
|
337
344
|
None, "--api-key", help="API Key override.", callback=api_key_context_callback
|
|
@@ -347,7 +354,7 @@ def byosnap(
|
|
|
347
354
|
byosnap_obj: ByoSnap = ByoSnap(
|
|
348
355
|
subcommand, ctx.obj['base_url'], ctx.obj['api_key'], sid,
|
|
349
356
|
name, desc, platform_type, language, tag, path, docker_file,
|
|
350
|
-
prefix, version, http_port, byosnap_profile
|
|
357
|
+
prefix, version, http_port, byosnap_profile, skip_build
|
|
351
358
|
)
|
|
352
359
|
getattr(byosnap_obj, subcommand.replace('-', '_'))()
|
|
353
360
|
success(f"BYOSnap {subcommand} complete")
|
|
@@ -390,11 +397,28 @@ def generate(
|
|
|
390
397
|
ctx: typer.Context,
|
|
391
398
|
# Required fields
|
|
392
399
|
subcommand: str = typer.Argument(
|
|
393
|
-
..., help=
|
|
400
|
+
..., help=(
|
|
401
|
+
"Generate Subcommands: " + \
|
|
402
|
+
", ".join(Generate.SUBCOMMANDS) + "." + " "
|
|
403
|
+
"Deprecation Notice: " + \
|
|
404
|
+
",".join(Generate.DEPRECATED_SOON_SUBCOMMANDS) + \
|
|
405
|
+
" will be deprecated soon. "
|
|
406
|
+
"Use `snapctl generate profile --category byosnap --out-path <output_path>` command instead."
|
|
407
|
+
)
|
|
408
|
+
),
|
|
409
|
+
category: Union[str, None] = typer.Option(
|
|
410
|
+
None, "--category",
|
|
411
|
+
help=(
|
|
412
|
+
"(req: profile, token) (profile: " +
|
|
413
|
+
", ".join(Generate.CATEGORIES['profile']) +
|
|
414
|
+
") (token: " + ", ".join(Generate.CATEGORIES['credentials']) + ')'
|
|
415
|
+
)
|
|
394
416
|
),
|
|
395
|
-
# byosnap-profile
|
|
417
|
+
# byosnap-profile, profile
|
|
396
418
|
out_path: Union[str, None] = typer.Option(
|
|
397
|
-
None, "--out-path", help=
|
|
419
|
+
None, "--out-path", help=(
|
|
420
|
+
"(req: byosnap-profile, profile, token) Path to output the byosnap profile"
|
|
421
|
+
)
|
|
398
422
|
),
|
|
399
423
|
# overrides
|
|
400
424
|
api_key: Union[str, None] = typer.Option(
|
|
@@ -410,14 +434,14 @@ def generate(
|
|
|
410
434
|
validate_command_context(ctx)
|
|
411
435
|
generate_obj: Generate = Generate(
|
|
412
436
|
subcommand, ctx.obj['base_url'], ctx.obj['api_key'],
|
|
413
|
-
out_path,
|
|
437
|
+
category, out_path,
|
|
414
438
|
)
|
|
415
439
|
getattr(generate_obj, subcommand.replace('-', '_'))()
|
|
416
440
|
success(f"Generate {subcommand} complete")
|
|
417
441
|
raise typer.Exit(code=SNAPCTL_SUCCESS)
|
|
418
442
|
|
|
419
443
|
|
|
420
|
-
@app.command()
|
|
444
|
+
@ app.command()
|
|
421
445
|
def snapend(
|
|
422
446
|
ctx: typer.Context,
|
|
423
447
|
# Required fields
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: snapctl
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.35.0
|
|
4
4
|
Summary: Snapser CLI Tool
|
|
5
5
|
Author: Ajinkya Apte
|
|
6
6
|
Author-email: aj@snapser.com
|
|
@@ -272,9 +272,11 @@ snapctl byosnap publish-image --help
|
|
|
272
272
|
# $byosnap_sid = Snap ID for your snap
|
|
273
273
|
# $image_tag = An image tag for your snap
|
|
274
274
|
# $code_root_path = Local code path where your Dockerfile is present
|
|
275
|
+
# $skip-build = true/false. Default is false. Pass this flag as true to skip the build and head straight to tag and push. Build step needs to run and tagged using the --tag you pass to the publish-image command for this to work.
|
|
275
276
|
# Example:
|
|
276
277
|
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --path /Users/DevName/Development/SnapserEngine/jinks_flask
|
|
277
278
|
snapctl byosnap publish-image $byosnap_sid --tag $image_tag --path $code_root_path
|
|
279
|
+
snapctl byosnap publish-image $byosnap_sid --tag $image_tag --skip-build
|
|
278
280
|
```
|
|
279
281
|
|
|
280
282
|
#### 7. byosnap publish-version
|
|
@@ -292,7 +294,7 @@ snapctl byosnap publish-version --help
|
|
|
292
294
|
# $prefix = Prefix for your snap Eg: /v1
|
|
293
295
|
# $version = Semantic version for your snap Eg: v0.0.1
|
|
294
296
|
# $ingress_port = Ingress port for your snap Eg: 5003
|
|
295
|
-
# $byosnap_profile = BYOSnap profile to configure dev, stage and prod settings for this snap. You can generate a base version of this file using the `snapctl generate byosnap
|
|
297
|
+
# $byosnap_profile = BYOSnap profile to configure dev, stage and prod settings for this snap. You can generate a base version of this file using the `snapctl generate profile --category byosnap --out-path <output_path>` command
|
|
296
298
|
# Example:
|
|
297
299
|
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --prefix /v1 --version v0.0.1 --http-port 5003 --byosnap-profile /Users/DevName/Development/SnapserEngine/jinks_flask/snapser-byosnap-profile.json
|
|
298
300
|
snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port --byosnap-profile $byosnap_profile
|
|
@@ -353,9 +355,11 @@ snapctl byogs publish --help
|
|
|
353
355
|
# Publish a new image
|
|
354
356
|
# $image_tag = An image tag for your snap
|
|
355
357
|
# $code_root_path = Local code path where your Dockerfile is present
|
|
358
|
+
# $skip-build = Default is false. Pass this flag as true to skip the build and head straight to tag and push. Build step needs to run and tagged using the --tag you pass to the publish-image command for this to work.
|
|
356
359
|
# Example:
|
|
357
360
|
# snapctl byogs publish --tag my-first-image --path /Users/DevName/Development/SnapserEngine/game_server
|
|
358
361
|
snapctl byogs publish --tag $image_tag --path $code_root_path
|
|
362
|
+
snapctl byogs publish --tag $image_tag --skip-build
|
|
359
363
|
```
|
|
360
364
|
|
|
361
365
|
|
|
@@ -393,11 +397,19 @@ See all the supported commands
|
|
|
393
397
|
snapctl generate --help
|
|
394
398
|
```
|
|
395
399
|
|
|
396
|
-
#### 2. BYOSnap Profile
|
|
400
|
+
#### 2. Generate BYOSnap Profile
|
|
397
401
|
Generate the base file for BYOSnap profile to be used in the `snapctl byosnap publish-version` command
|
|
398
402
|
|
|
399
403
|
```
|
|
400
|
-
snapctl generate
|
|
404
|
+
snapctl generate profile --category "byosnap" --out-path $output_path
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### 3. Generate ECR Credentials
|
|
409
|
+
Generate the ECR credentials. Game studios can use these credentials to self publish their images to Snapser.
|
|
410
|
+
|
|
411
|
+
```
|
|
412
|
+
snapctl generate credentials --category "ecr" --out-path $output_path
|
|
401
413
|
|
|
402
414
|
```
|
|
403
415
|
|
|
@@ -596,5 +608,6 @@ snapctl snapend state $snapend_id
|
|
|
596
608
|
| Error Code | Description |
|
|
597
609
|
|------------|----------------------------------------------------------|
|
|
598
610
|
| 80 | Generic generate error |
|
|
599
|
-
| 81 | Generate
|
|
611
|
+
| 81 | Generate profile error |
|
|
612
|
+
| 82 | Generate credentials error |
|
|
600
613
|
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
snapctl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
snapctl/__main__.py,sha256=43jKoTk8b85hk_MT6499N3ruHdEfM8WBImd_-3VzjI8,116
|
|
3
3
|
snapctl/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
snapctl/commands/byogs.py,sha256=
|
|
5
|
-
snapctl/commands/byosnap.py,sha256=
|
|
4
|
+
snapctl/commands/byogs.py,sha256=NYQLqFnaXQSTqwSfBCMYtDprDtu1bosEIlCf2jMUZdI,12987
|
|
5
|
+
snapctl/commands/byosnap.py,sha256=Pd0IAJsyaq8EhyEJwHEQamQP9ud4nDu8mfkeqcj_188,28512
|
|
6
6
|
snapctl/commands/game.py,sha256=7255xoGszkk2pPcc2sRJP98-3S0qfSKXFOl5CrsbCSY,4349
|
|
7
|
-
snapctl/commands/generate.py,sha256=
|
|
7
|
+
snapctl/commands/generate.py,sha256=l1avy7YlCgscCBT40yh9L8OjD7ONMUE96BB2M553g30,7849
|
|
8
8
|
snapctl/commands/snapend.py,sha256=cxBMNMfXyQeLdg5NyKZ2ujjUG7zYxOgyjmeAoD27t7I,29922
|
|
9
9
|
snapctl/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
snapctl/config/constants.py,sha256=
|
|
10
|
+
snapctl/config/constants.py,sha256=UPg9ycbx2OF6SIrt0X4SByMskcu39rnVxFdopc8Ga7M,2735
|
|
11
11
|
snapctl/config/endpoints.py,sha256=VAeOmx3k3ukB-9XuGI65KtCJwFK-KFgzor-UWE8JU0g,297
|
|
12
|
-
snapctl/config/hashes.py,sha256=
|
|
13
|
-
snapctl/main.py,sha256=
|
|
12
|
+
snapctl/config/hashes.py,sha256=KGzZCVeM3nI3AC4zOYkw-j0PVr9gAGrRefRI30Xvglg,3807
|
|
13
|
+
snapctl/main.py,sha256=OW4Ct80h-BxMO4CvizTNNu9IasguV6gXWKXiC6HZBMc,19241
|
|
14
14
|
snapctl/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
snapctl/types/definitions.py,sha256=EQzLeiXkJ8ISRlCqHMviNVsWWpmhWjpKaOBLdlvOTmY,644
|
|
16
16
|
snapctl/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
snapctl/utils/echo.py,sha256=bvirxTlxv-EAwyf4FT0yAqY5fsevp3yimxKmgQV73Fc,941
|
|
18
18
|
snapctl/utils/helper.py,sha256=jPXQnSbdOnktJdLotBugdHfVwkap-5MoApOmhJ-AsqA,3287
|
|
19
|
-
snapctl-0.
|
|
20
|
-
snapctl-0.
|
|
21
|
-
snapctl-0.
|
|
22
|
-
snapctl-0.
|
|
23
|
-
snapctl-0.
|
|
19
|
+
snapctl-0.35.0.dist-info/LICENSE,sha256=6AcXm54KFSpmUI1ji9NIBd4Xl-DtjTqiyjBzfVb_CEk,2804
|
|
20
|
+
snapctl-0.35.0.dist-info/METADATA,sha256=GaRoEVhkT5cGjpKMeGZmztpnm0RVTXjUpliPPzmIXb0,21045
|
|
21
|
+
snapctl-0.35.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
22
|
+
snapctl-0.35.0.dist-info/entry_points.txt,sha256=tkKW9MzmFdRs6Bgkv29G78i9WEBK4WIOWunPfe3t2Wg,44
|
|
23
|
+
snapctl-0.35.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|