snapctl 0.32.1__tar.gz → 0.35.0__tar.gz
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-0.32.1 → snapctl-0.35.0}/PKG-INFO +43 -8
- {snapctl-0.32.1 → snapctl-0.35.0}/README.md +42 -7
- {snapctl-0.32.1 → snapctl-0.35.0}/pyproject.toml +1 -1
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/commands/byogs.py +14 -10
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/commands/byosnap.py +17 -11
- snapctl-0.35.0/snapctl/commands/generate.py +215 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/config/constants.py +3 -2
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/config/hashes.py +21 -5
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/main.py +35 -11
- snapctl-0.32.1/snapctl/commands/generate.py +0 -93
- {snapctl-0.32.1 → snapctl-0.35.0}/LICENSE +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/__init__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/__main__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/commands/__init__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/commands/game.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/commands/snapend.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/config/__init__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/config/endpoints.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/types/__init__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/types/definitions.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/utils/__init__.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/utils/echo.py +0 -0
- {snapctl-0.32.1 → snapctl-0.35.0}/snapctl/utils/helper.py +0 -0
|
@@ -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
|
|
@@ -177,6 +177,7 @@ snapctl --help
|
|
|
177
177
|
```
|
|
178
178
|
|
|
179
179
|
### BYO Snap - Bring your own Snap
|
|
180
|
+
Snapctl commands for your custom code
|
|
180
181
|
|
|
181
182
|
#### 1. byosnap help
|
|
182
183
|
|
|
@@ -208,7 +209,7 @@ snapctl byosnap create --help
|
|
|
208
209
|
snapctl byosnap create $byosnap_sid --name "$name" --desc "$desc" --platform "$platform" --language "$language"
|
|
209
210
|
```
|
|
210
211
|
|
|
211
|
-
|
|
212
|
+
#### 3. byosnap build
|
|
212
213
|
|
|
213
214
|
Build your snap image
|
|
214
215
|
|
|
@@ -225,7 +226,7 @@ snapctl byosnap build --help
|
|
|
225
226
|
snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path
|
|
226
227
|
```
|
|
227
228
|
|
|
228
|
-
|
|
229
|
+
#### 4. byosnap push
|
|
229
230
|
|
|
230
231
|
Push your snap image to Snapser
|
|
231
232
|
|
|
@@ -271,9 +272,11 @@ snapctl byosnap publish-image --help
|
|
|
271
272
|
# $byosnap_sid = Snap ID for your snap
|
|
272
273
|
# $image_tag = An image tag for your snap
|
|
273
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.
|
|
274
276
|
# Example:
|
|
275
277
|
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --path /Users/DevName/Development/SnapserEngine/jinks_flask
|
|
276
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
|
|
277
280
|
```
|
|
278
281
|
|
|
279
282
|
#### 7. byosnap publish-version
|
|
@@ -291,12 +294,14 @@ snapctl byosnap publish-version --help
|
|
|
291
294
|
# $prefix = Prefix for your snap Eg: /v1
|
|
292
295
|
# $version = Semantic version for your snap Eg: v0.0.1
|
|
293
296
|
# $ingress_port = Ingress port for your snap Eg: 5003
|
|
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
|
|
294
298
|
# Example:
|
|
295
|
-
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --prefix /v1 --version v0.0.1 --http-port 5003
|
|
296
|
-
snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port
|
|
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
|
|
300
|
+
snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port --byosnap-profile $byosnap_profile
|
|
297
301
|
```
|
|
298
302
|
|
|
299
303
|
### BYO Game Server - Bring your own Game Server
|
|
304
|
+
Snapctl commands for your custom game server
|
|
300
305
|
|
|
301
306
|
#### 1. byogs help
|
|
302
307
|
|
|
@@ -350,21 +355,24 @@ snapctl byogs publish --help
|
|
|
350
355
|
# Publish a new image
|
|
351
356
|
# $image_tag = An image tag for your snap
|
|
352
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.
|
|
353
359
|
# Example:
|
|
354
360
|
# snapctl byogs publish --tag my-first-image --path /Users/DevName/Development/SnapserEngine/game_server
|
|
355
361
|
snapctl byogs publish --tag $image_tag --path $code_root_path
|
|
362
|
+
snapctl byogs publish --tag $image_tag --skip-build
|
|
356
363
|
```
|
|
357
364
|
|
|
358
365
|
|
|
359
366
|
### Game
|
|
367
|
+
Snapctl commands for your game
|
|
360
368
|
|
|
361
|
-
#### 1.
|
|
369
|
+
#### 1. game help
|
|
362
370
|
|
|
363
371
|
See all the supported commands
|
|
364
372
|
|
|
365
373
|
```
|
|
366
374
|
# Help for the byogs command
|
|
367
|
-
snapctl
|
|
375
|
+
snapctl game --help
|
|
368
376
|
```
|
|
369
377
|
|
|
370
378
|
#### 2. Create a game
|
|
@@ -379,8 +387,34 @@ List all the games
|
|
|
379
387
|
snapctl game enumerate
|
|
380
388
|
```
|
|
381
389
|
|
|
390
|
+
### Generate
|
|
391
|
+
Generator tool to help generate base files to be used in other commands
|
|
392
|
+
|
|
393
|
+
#### 1. generate help
|
|
394
|
+
See all the supported commands
|
|
395
|
+
```
|
|
396
|
+
# Help for the generate command
|
|
397
|
+
snapctl generate --help
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### 2. Generate BYOSnap Profile
|
|
401
|
+
Generate the base file for BYOSnap profile to be used in the `snapctl byosnap publish-version` command
|
|
402
|
+
|
|
403
|
+
```
|
|
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
|
|
413
|
+
|
|
414
|
+
```
|
|
382
415
|
|
|
383
416
|
### Snapend
|
|
417
|
+
Snapctl commands for your snapend
|
|
384
418
|
|
|
385
419
|
#### 1. snapend help
|
|
386
420
|
|
|
@@ -574,5 +608,6 @@ snapctl snapend state $snapend_id
|
|
|
574
608
|
| Error Code | Description |
|
|
575
609
|
|------------|----------------------------------------------------------|
|
|
576
610
|
| 80 | Generic generate error |
|
|
577
|
-
| 81 | Generate
|
|
611
|
+
| 81 | Generate profile error |
|
|
612
|
+
| 82 | Generate credentials error |
|
|
578
613
|
|
|
@@ -158,6 +158,7 @@ snapctl --help
|
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
### BYO Snap - Bring your own Snap
|
|
161
|
+
Snapctl commands for your custom code
|
|
161
162
|
|
|
162
163
|
#### 1. byosnap help
|
|
163
164
|
|
|
@@ -189,7 +190,7 @@ snapctl byosnap create --help
|
|
|
189
190
|
snapctl byosnap create $byosnap_sid --name "$name" --desc "$desc" --platform "$platform" --language "$language"
|
|
190
191
|
```
|
|
191
192
|
|
|
192
|
-
|
|
193
|
+
#### 3. byosnap build
|
|
193
194
|
|
|
194
195
|
Build your snap image
|
|
195
196
|
|
|
@@ -206,7 +207,7 @@ snapctl byosnap build --help
|
|
|
206
207
|
snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path
|
|
207
208
|
```
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
#### 4. byosnap push
|
|
210
211
|
|
|
211
212
|
Push your snap image to Snapser
|
|
212
213
|
|
|
@@ -252,9 +253,11 @@ snapctl byosnap publish-image --help
|
|
|
252
253
|
# $byosnap_sid = Snap ID for your snap
|
|
253
254
|
# $image_tag = An image tag for your snap
|
|
254
255
|
# $code_root_path = Local code path where your Dockerfile is present
|
|
256
|
+
# $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.
|
|
255
257
|
# Example:
|
|
256
258
|
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --path /Users/DevName/Development/SnapserEngine/jinks_flask
|
|
257
259
|
snapctl byosnap publish-image $byosnap_sid --tag $image_tag --path $code_root_path
|
|
260
|
+
snapctl byosnap publish-image $byosnap_sid --tag $image_tag --skip-build
|
|
258
261
|
```
|
|
259
262
|
|
|
260
263
|
#### 7. byosnap publish-version
|
|
@@ -272,12 +275,14 @@ snapctl byosnap publish-version --help
|
|
|
272
275
|
# $prefix = Prefix for your snap Eg: /v1
|
|
273
276
|
# $version = Semantic version for your snap Eg: v0.0.1
|
|
274
277
|
# $ingress_port = Ingress port for your snap Eg: 5003
|
|
278
|
+
# $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
|
|
275
279
|
# Example:
|
|
276
|
-
# snapctl byosnap publish-image byosnap-jinks-flask --tag my-first-image --prefix /v1 --version v0.0.1 --http-port 5003
|
|
277
|
-
snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port
|
|
280
|
+
# 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
|
|
281
|
+
snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port --byosnap-profile $byosnap_profile
|
|
278
282
|
```
|
|
279
283
|
|
|
280
284
|
### BYO Game Server - Bring your own Game Server
|
|
285
|
+
Snapctl commands for your custom game server
|
|
281
286
|
|
|
282
287
|
#### 1. byogs help
|
|
283
288
|
|
|
@@ -331,21 +336,24 @@ snapctl byogs publish --help
|
|
|
331
336
|
# Publish a new image
|
|
332
337
|
# $image_tag = An image tag for your snap
|
|
333
338
|
# $code_root_path = Local code path where your Dockerfile is present
|
|
339
|
+
# $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.
|
|
334
340
|
# Example:
|
|
335
341
|
# snapctl byogs publish --tag my-first-image --path /Users/DevName/Development/SnapserEngine/game_server
|
|
336
342
|
snapctl byogs publish --tag $image_tag --path $code_root_path
|
|
343
|
+
snapctl byogs publish --tag $image_tag --skip-build
|
|
337
344
|
```
|
|
338
345
|
|
|
339
346
|
|
|
340
347
|
### Game
|
|
348
|
+
Snapctl commands for your game
|
|
341
349
|
|
|
342
|
-
#### 1.
|
|
350
|
+
#### 1. game help
|
|
343
351
|
|
|
344
352
|
See all the supported commands
|
|
345
353
|
|
|
346
354
|
```
|
|
347
355
|
# Help for the byogs command
|
|
348
|
-
snapctl
|
|
356
|
+
snapctl game --help
|
|
349
357
|
```
|
|
350
358
|
|
|
351
359
|
#### 2. Create a game
|
|
@@ -360,8 +368,34 @@ List all the games
|
|
|
360
368
|
snapctl game enumerate
|
|
361
369
|
```
|
|
362
370
|
|
|
371
|
+
### Generate
|
|
372
|
+
Generator tool to help generate base files to be used in other commands
|
|
373
|
+
|
|
374
|
+
#### 1. generate help
|
|
375
|
+
See all the supported commands
|
|
376
|
+
```
|
|
377
|
+
# Help for the generate command
|
|
378
|
+
snapctl generate --help
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
#### 2. Generate BYOSnap Profile
|
|
382
|
+
Generate the base file for BYOSnap profile to be used in the `snapctl byosnap publish-version` command
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
snapctl generate profile --category "byosnap" --out-path $output_path
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### 3. Generate ECR Credentials
|
|
390
|
+
Generate the ECR credentials. Game studios can use these credentials to self publish their images to Snapser.
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
snapctl generate credentials --category "ecr" --out-path $output_path
|
|
394
|
+
|
|
395
|
+
```
|
|
363
396
|
|
|
364
397
|
### Snapend
|
|
398
|
+
Snapctl commands for your snapend
|
|
365
399
|
|
|
366
400
|
#### 1. snapend help
|
|
367
401
|
|
|
@@ -555,4 +589,5 @@ snapctl snapend state $snapend_id
|
|
|
555
589
|
| Error Code | Description |
|
|
556
590
|
|------------|----------------------------------------------------------|
|
|
557
591
|
| 80 | Generic generate error |
|
|
558
|
-
| 81 | Generate
|
|
592
|
+
| 81 | Generate profile error |
|
|
593
|
+
| 82 | Generate credentials error |
|
|
@@ -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')
|
|
@@ -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:
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generate CLI commands
|
|
3
|
+
"""
|
|
4
|
+
import base64
|
|
5
|
+
from binascii import Error as BinasciiError
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from typing import Union
|
|
9
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
10
|
+
from snapctl.config.constants import SNAPCTL_INPUT_ERROR, \
|
|
11
|
+
SNAPCTL_GENERATE_GENERIC_ERROR, SNAPCTL_GENERATE_PROFILE_ERROR, \
|
|
12
|
+
SNAPCTL_GENERATE_CREDENTIALS_ERROR
|
|
13
|
+
from snapctl.config.hashes import BYOSNAP_TEMPLATE
|
|
14
|
+
from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Generate:
|
|
18
|
+
"""
|
|
19
|
+
Generate CLI commands
|
|
20
|
+
"""
|
|
21
|
+
SUBCOMMANDS = ['byosnap-profile', 'profile', 'credentials']
|
|
22
|
+
DEPRECATED_SOON_SUBCOMMANDS = ['byosnap-profile']
|
|
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
|
+
}
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self, subcommand: str, base_url: str, api_key: str | None,
|
|
32
|
+
category: str | None,
|
|
33
|
+
out_path: Union[str, None]
|
|
34
|
+
) -> None:
|
|
35
|
+
self.subcommand: str = subcommand
|
|
36
|
+
self.base_url: str = base_url
|
|
37
|
+
self.api_key: str = api_key
|
|
38
|
+
self.category: str | None = category
|
|
39
|
+
self.out_path: Union[str, None] = out_path
|
|
40
|
+
# Validate input
|
|
41
|
+
self.validate_input()
|
|
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
|
|
58
|
+
# Validator
|
|
59
|
+
|
|
60
|
+
def validate_input(self) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Validator
|
|
63
|
+
"""
|
|
64
|
+
if self.subcommand not in Generate.SUBCOMMANDS:
|
|
65
|
+
snapctl_error(
|
|
66
|
+
f"Invalid command {self.subcommand}. Valid command are "
|
|
67
|
+
f"{Generate.SUBCOMMANDS}",
|
|
68
|
+
SNAPCTL_INPUT_ERROR
|
|
69
|
+
)
|
|
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']:
|
|
85
|
+
snapctl_error(
|
|
86
|
+
f"Invalid category {self.category}. Valid category are "
|
|
87
|
+
f"{Generate.CATEGORIES['credentials']}",
|
|
88
|
+
SNAPCTL_INPUT_ERROR
|
|
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
|
+
)
|
|
102
|
+
|
|
103
|
+
def byosnap_profile(self) -> 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
|
+
"BYOSNAP Profile generation successful. "
|
|
129
|
+
f"{Generate.BYOSNAP_PROFILE_FN} saved at {file_save_path}",
|
|
130
|
+
progress
|
|
131
|
+
)
|
|
132
|
+
except (IOError, OSError) as file_error:
|
|
133
|
+
snapctl_error(f"File error: {file_error}",
|
|
134
|
+
SNAPCTL_GENERATE_PROFILE_ERROR, progress)
|
|
135
|
+
except json.JSONDecodeError as json_error:
|
|
136
|
+
snapctl_error(f"JSON error: {json_error}",
|
|
137
|
+
SNAPCTL_GENERATE_PROFILE_ERROR, progress)
|
|
138
|
+
snapctl_error(
|
|
139
|
+
"Failed to generate BYOSNAP Profile",
|
|
140
|
+
SNAPCTL_GENERATE_PROFILE_ERROR,
|
|
141
|
+
progress
|
|
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()
|
|
@@ -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
|
|
@@ -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
|
}
|
|
@@ -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,93 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Generate CLI commands
|
|
3
|
-
"""
|
|
4
|
-
import json
|
|
5
|
-
import os
|
|
6
|
-
from typing import Union
|
|
7
|
-
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
8
|
-
from snapctl.config.constants import SNAPCTL_INPUT_ERROR, \
|
|
9
|
-
SNAPCTL_GENERATE_GENERIC_ERROR
|
|
10
|
-
from snapctl.config.hashes import BYOSNAP_TEMPLATE
|
|
11
|
-
from snapctl.utils.echo import error
|
|
12
|
-
from snapctl.utils.helper import snapctl_error, snapctl_success
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class Generate:
|
|
16
|
-
"""
|
|
17
|
-
Generate CLI commands
|
|
18
|
-
"""
|
|
19
|
-
SUBCOMMANDS = ['byosnap-profile']
|
|
20
|
-
BYOSNAP_PROFILE_FN = 'snapser-byosnap-profile.json'
|
|
21
|
-
|
|
22
|
-
def __init__(
|
|
23
|
-
self, subcommand: str, base_url: str, api_key: str | None,
|
|
24
|
-
out_path: Union[str, None]
|
|
25
|
-
) -> None:
|
|
26
|
-
self.subcommand: str = subcommand
|
|
27
|
-
self.base_url: str = base_url
|
|
28
|
-
self.api_key: str = api_key
|
|
29
|
-
self.out_path: Union[str, None] = out_path
|
|
30
|
-
# Validate input
|
|
31
|
-
self.validate_input()
|
|
32
|
-
|
|
33
|
-
# Validator
|
|
34
|
-
|
|
35
|
-
def validate_input(self) -> None:
|
|
36
|
-
"""
|
|
37
|
-
Validator
|
|
38
|
-
"""
|
|
39
|
-
if self.subcommand not in Generate.SUBCOMMANDS:
|
|
40
|
-
snapctl_error(
|
|
41
|
-
f"Invalid command {self.subcommand}. Valid command are "
|
|
42
|
-
f"{Generate.SUBCOMMANDS}",
|
|
43
|
-
SNAPCTL_INPUT_ERROR
|
|
44
|
-
)
|
|
45
|
-
if self.subcommand in ['byosnap-profile']:
|
|
46
|
-
# Check path
|
|
47
|
-
if self.out_path and not os.path.isdir(self.out_path):
|
|
48
|
-
snapctl_error(
|
|
49
|
-
f"Invalid path {self.out_path}. Wont be able to "
|
|
50
|
-
"store the byosnap-profile.json file",
|
|
51
|
-
SNAPCTL_INPUT_ERROR
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
def byosnap_profile(self) -> None:
|
|
55
|
-
"""
|
|
56
|
-
Generate snapser-byosnap-profile.json
|
|
57
|
-
"""
|
|
58
|
-
progress = Progress(
|
|
59
|
-
SpinnerColumn(),
|
|
60
|
-
TextColumn("[progress.description]{task.description}"),
|
|
61
|
-
transient=True,
|
|
62
|
-
)
|
|
63
|
-
progress.start()
|
|
64
|
-
progress.add_task(
|
|
65
|
-
description='Promoting your staging snapend...', total=None)
|
|
66
|
-
try:
|
|
67
|
-
if self.out_path is not None:
|
|
68
|
-
file_save_path = os.path.join(
|
|
69
|
-
self.out_path, Generate.BYOSNAP_PROFILE_FN)
|
|
70
|
-
else:
|
|
71
|
-
file_save_path = os.path.join(
|
|
72
|
-
os.getcwd(), Generate.BYOSNAP_PROFILE_FN)
|
|
73
|
-
file_written = False
|
|
74
|
-
with open(file_save_path, "w") as file:
|
|
75
|
-
json.dump(BYOSNAP_TEMPLATE, file, indent=4)
|
|
76
|
-
file_written = True
|
|
77
|
-
if file_written:
|
|
78
|
-
snapctl_success(
|
|
79
|
-
"BYOSNAP Profile generation successful. "
|
|
80
|
-
f"{Generate.BYOSNAP_PROFILE_FN} saved at {file_save_path}",
|
|
81
|
-
progress
|
|
82
|
-
)
|
|
83
|
-
except (IOError, OSError) as file_error:
|
|
84
|
-
snapctl_error(f"File error: {file_error}",
|
|
85
|
-
SNAPCTL_GENERATE_GENERIC_ERROR, progress)
|
|
86
|
-
except json.JSONDecodeError as json_error:
|
|
87
|
-
snapctl_error(f"JSON error: {json_error}",
|
|
88
|
-
SNAPCTL_GENERATE_GENERIC_ERROR, progress)
|
|
89
|
-
snapctl_error(
|
|
90
|
-
"Failed to generate BYOSNAP Profile",
|
|
91
|
-
SNAPCTL_GENERATE_GENERIC_ERROR,
|
|
92
|
-
progress
|
|
93
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|