snapctl 0.43.0__tar.gz → 0.43.2__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: snapctl
3
- Version: 0.43.0
3
+ Version: 0.43.2
4
4
  Summary: Snapser CLI Tool
5
5
  Author: Ajinkya Apte
6
6
  Author-email: aj@snapser.com
@@ -189,14 +189,68 @@ Snapctl commands for your custom code
189
189
 
190
190
  #### 1. byosnap help
191
191
 
192
- See all the supported commands
192
+ See all the supported commands. You should mainly need the `publish` and `sync` commands.
193
+ All the others are for CRUD operations.
193
194
 
194
195
  ```
195
196
  # Help for the byosnap command
196
197
  snapctl byosnap --help
197
198
  ```
199
+ #### 2. publish
200
+
201
+ This command allows you to create and publish your BYOSnap. Running this command will first create a BYOSnap namespace on Snapser if not present. Then it will build and publish your code to your own
202
+ private ECR repo on Snapser. Finally it will assign a version to your BYOSnap so that you
203
+ can deploy it.
204
+
205
+ **Requirements**:
206
+ - This command needs docker.
207
+ - This command needs a BYOSnap profile. BYOSnap profile, holds information about
208
+ your BYOSnap like, name, description, etc and hardware requirements like CPU, Memory. We
209
+ recommend you store this file at the root of your BYOSnap and also add it to version control.
210
+ You can generate it using `snapctl generate profile --category byosnap --out-path $outputPath`.
211
+
212
+ ```
213
+ # Help for the byosnap command
214
+ snapctl byosnap publish --help
215
+
216
+ # Create and publish your BYOSnap
217
+ # $byosnap_sid = Snap ID for your snap
218
+ # $version = Semantic version for your snap Eg: v0.0.1
219
+ # $code_root_path = Local code path where your Dockerfile is present
220
+ # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, snapser-byosnap-profile.json, swagger.json and README.md at the root directory of your Snap.
221
+ # $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 tag using the --tag you pass to the publish-image command for this to work. Make sure the tag matches the version number you are passing.
222
+ # Example:
223
+ snapctl byosnap publish byosnap-jinks-flask --version "v0.0.1" --path /Users/DevName/Development/SnapserEngine/jinks_flask
224
+ snapctl byosnap publish $byosnap_sid --version $version --path $code_root_path
225
+ ```
226
+
227
+ #### 3. byosnap sync
228
+
229
+ This command is for development purposes. It allows developers to rapidly build, update and push their BYOSnap to a dev Snapend. Simply, make changes to your code locally, and then run this command to deploy your BYOSnap straight to your development Snapend.
230
+
231
+ **Requirements**:
232
+ - This command needs docker.
233
+
234
+ **IMPORTANT**: This command will only work for Dev Snapends. Additionally if the version you are using in this command happens to be used by a staging or a production snapend then `sync` will not work. We do this to ensure that your staging and production BYOSnap images do not get impacted.
235
+
236
+ ```
237
+ # Help for the byosnap command
238
+ snapctl byosnap sync --help
239
+
240
+ # Deploy local code straight to your Snapend
241
+ # $byosnap_sid = Snap ID for your snap
242
+ # $code_root_path = Local code path where your Dockerfile is present
243
+ # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, swagger.json and README.md in the root directory of your Snap.
244
+ # $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.
245
+ # $tag = Semantic version for your snap Eg: v0.0.1
246
+ # $version =
247
+ # $snapend_id = Dev Snapend Id
248
+ # Example:
249
+ snapctl byosnap sync byosnap-jinks-flask --path /Users/DevName/Development/SnapserEngine/jinks_flask --version "v0.0.11" --snapend-id "jxmmfryo"
250
+ snapctl byosnap sync $byosnap_sid --path $code_root_path --version $version --snapend-id $snapend_id
251
+ ```
198
252
 
199
- #### 2. byosnap create
253
+ #### 4. byosnap create
200
254
 
201
255
  Create a custom snap. Note that you will have to build, push and publish your snap image, for it to be useable
202
256
  in a Snapend.
@@ -217,7 +271,7 @@ snapctl byosnap create --help
217
271
  snapctl byosnap create $byosnap_sid --name "$name" --desc "$desc" --platform "$platform" --language "$language"
218
272
  ```
219
273
 
220
- #### 3. byosnap build
274
+ #### 5. byosnap build
221
275
 
222
276
  Build your snap image
223
277
 
@@ -236,7 +290,7 @@ snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path
236
290
  snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path --resources-path $resources_path
237
291
  ```
238
292
 
239
- #### 4. byosnap push
293
+ #### 6. byosnap push
240
294
 
241
295
  Push your snap image to Snapser
242
296
 
@@ -252,7 +306,7 @@ snapctl byosnap push --help
252
306
  snapctl byosnap push $byosnap_sid --tag $image_tag
253
307
  ```
254
308
 
255
- #### 5. byosnap upload-docs
309
+ #### 7. byosnap upload-docs
256
310
 
257
311
  Upload swagger.json and README.md for you Snap
258
312
 
@@ -269,7 +323,7 @@ snapctl byosnap upload-docs --help
269
323
  snapctl byosnap upload-docs $byosnap_sid --tag $image_tag --resources-path $resources_path
270
324
  ```
271
325
 
272
- #### 6. byosnap publish-image
326
+ #### 8. byosnap publish-image
273
327
 
274
328
  Publish a custom snap code image. This command executes, `build`, `push` and `upload-docs` one
275
329
  after the other.
@@ -295,7 +349,7 @@ snapctl byosnap publish-image $byosnap_sid --tag $image_tag --path $code_root_pa
295
349
  snapctl byosnap publish-image $byosnap_sid --tag $image_tag --skip-build
296
350
  ```
297
351
 
298
- #### 7. byosnap publish-version
352
+ #### 9. byosnap publish-version
299
353
 
300
354
  Publish a new version for your Snap. Only after your Snap version is published, you will be able
301
355
  to use your snap in your Snapend. This command should be run after `push` or `publish-image` commands.
@@ -310,40 +364,11 @@ snapctl byosnap publish-version --help
310
364
  # Publish a new image
311
365
  # $byosnap_sid = Snap ID for your snap
312
366
  # $image_tag = An image tag for your snap
313
- # $prefix = Prefix for your snap Eg: /v1
314
367
  # $version = Semantic version for your snap Eg: v0.0.1
315
- # $ingress_port = Ingress port for your snap Eg: 5003
316
- # $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
317
- # Example:
318
- # 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
319
- snapctl byosnap publish-version $byosnap_sid --tag $image_tag --prefix $prefix --version $version --http-port $ingress_port --byosnap-profile $byosnap_profile
320
- ```
321
-
322
- #### 8. byosnap sync
323
-
324
- This command is for development purposes. It allows developers to rapidly build, update and push their
325
- BYOSnap to a dev Snapend. Simply, make changes to your code locally, and then run this command to deploy
326
- your BYOSnap straight to your development Snapend.
327
-
328
- IMPORTANT: This command will only work for Dev Snapends. Additionally if the tag you are using in this
329
- command happens to be used by a staging or a production snapend then `sync` will not work. We do this to
330
- ensure that your staging and production BYOSnap images do not get impacted.
331
-
332
- ```
333
- # Help for the byosnap command
334
- snapctl byosnap sync --help
335
-
336
- # Publish a new image
337
- # $byosnap_sid = Snap ID for your snap
338
- # $code_root_path = Local code path where your Dockerfile is present
339
- # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, swagger.json and README.md in the root directory of your Snap.
340
- # $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.
341
- # $image_tag = An image tag for your snap. Note snapctl adds a timestamp, allowing you to use the same command.
342
- # $version = Semantic version for your snap Eg: v0.0.1
343
- # $snapend_id = Dev Snapend Id
368
+ # $byosnapProfilePath = Path to the snapser-byosnap-profile.json 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
344
369
  # Example:
345
- snapctl byosnap sync byosnap-jinks-flask --path /Users/DevName/Development/SnapserEngine/jinks_flask --tag my-first-image --version "v0.0.11" --snapend-id "jxmmfryo"
346
- snapctl byosnap sync $byosnap_sid --path $code_root_path --tag $image_tag --version $version --snapend-id $snapend_id
370
+ # snapctl byosnap publish-version byosnap-jinks-flask --tag my-first-image --version v0.0.1 --path /Users/DevName/Development/SnapserEngine/jinks_flask
371
+ snapctl byosnap publish-version $byosnap_sid --tag $image_tag --version $version --path $byosnapProfilePath
347
372
  ```
348
373
 
349
374
  ### BYO Game Server - Bring your own Game Server
@@ -170,14 +170,68 @@ Snapctl commands for your custom code
170
170
 
171
171
  #### 1. byosnap help
172
172
 
173
- See all the supported commands
173
+ See all the supported commands. You should mainly need the `publish` and `sync` commands.
174
+ All the others are for CRUD operations.
174
175
 
175
176
  ```
176
177
  # Help for the byosnap command
177
178
  snapctl byosnap --help
178
179
  ```
180
+ #### 2. publish
181
+
182
+ This command allows you to create and publish your BYOSnap. Running this command will first create a BYOSnap namespace on Snapser if not present. Then it will build and publish your code to your own
183
+ private ECR repo on Snapser. Finally it will assign a version to your BYOSnap so that you
184
+ can deploy it.
185
+
186
+ **Requirements**:
187
+ - This command needs docker.
188
+ - This command needs a BYOSnap profile. BYOSnap profile, holds information about
189
+ your BYOSnap like, name, description, etc and hardware requirements like CPU, Memory. We
190
+ recommend you store this file at the root of your BYOSnap and also add it to version control.
191
+ You can generate it using `snapctl generate profile --category byosnap --out-path $outputPath`.
192
+
193
+ ```
194
+ # Help for the byosnap command
195
+ snapctl byosnap publish --help
196
+
197
+ # Create and publish your BYOSnap
198
+ # $byosnap_sid = Snap ID for your snap
199
+ # $version = Semantic version for your snap Eg: v0.0.1
200
+ # $code_root_path = Local code path where your Dockerfile is present
201
+ # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, snapser-byosnap-profile.json, swagger.json and README.md at the root directory of your Snap.
202
+ # $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 tag using the --tag you pass to the publish-image command for this to work. Make sure the tag matches the version number you are passing.
203
+ # Example:
204
+ snapctl byosnap publish byosnap-jinks-flask --version "v0.0.1" --path /Users/DevName/Development/SnapserEngine/jinks_flask
205
+ snapctl byosnap publish $byosnap_sid --version $version --path $code_root_path
206
+ ```
207
+
208
+ #### 3. byosnap sync
209
+
210
+ This command is for development purposes. It allows developers to rapidly build, update and push their BYOSnap to a dev Snapend. Simply, make changes to your code locally, and then run this command to deploy your BYOSnap straight to your development Snapend.
211
+
212
+ **Requirements**:
213
+ - This command needs docker.
214
+
215
+ **IMPORTANT**: This command will only work for Dev Snapends. Additionally if the version you are using in this command happens to be used by a staging or a production snapend then `sync` will not work. We do this to ensure that your staging and production BYOSnap images do not get impacted.
216
+
217
+ ```
218
+ # Help for the byosnap command
219
+ snapctl byosnap sync --help
220
+
221
+ # Deploy local code straight to your Snapend
222
+ # $byosnap_sid = Snap ID for your snap
223
+ # $code_root_path = Local code path where your Dockerfile is present
224
+ # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, swagger.json and README.md in the root directory of your Snap.
225
+ # $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.
226
+ # $tag = Semantic version for your snap Eg: v0.0.1
227
+ # $version =
228
+ # $snapend_id = Dev Snapend Id
229
+ # Example:
230
+ snapctl byosnap sync byosnap-jinks-flask --path /Users/DevName/Development/SnapserEngine/jinks_flask --version "v0.0.11" --snapend-id "jxmmfryo"
231
+ snapctl byosnap sync $byosnap_sid --path $code_root_path --version $version --snapend-id $snapend_id
232
+ ```
179
233
 
180
- #### 2. byosnap create
234
+ #### 4. byosnap create
181
235
 
182
236
  Create a custom snap. Note that you will have to build, push and publish your snap image, for it to be useable
183
237
  in a Snapend.
@@ -198,7 +252,7 @@ snapctl byosnap create --help
198
252
  snapctl byosnap create $byosnap_sid --name "$name" --desc "$desc" --platform "$platform" --language "$language"
199
253
  ```
200
254
 
201
- #### 3. byosnap build
255
+ #### 5. byosnap build
202
256
 
203
257
  Build your snap image
204
258
 
@@ -217,7 +271,7 @@ snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path
217
271
  snapctl byosnap build $byosnap_sid --tag $image_tag --path $code_root_path --resources-path $resources_path
218
272
  ```
219
273
 
220
- #### 4. byosnap push
274
+ #### 6. byosnap push
221
275
 
222
276
  Push your snap image to Snapser
223
277
 
@@ -233,7 +287,7 @@ snapctl byosnap push --help
233
287
  snapctl byosnap push $byosnap_sid --tag $image_tag
234
288
  ```
235
289
 
236
- #### 5. byosnap upload-docs
290
+ #### 7. byosnap upload-docs
237
291
 
238
292
  Upload swagger.json and README.md for you Snap
239
293
 
@@ -250,7 +304,7 @@ snapctl byosnap upload-docs --help
250
304
  snapctl byosnap upload-docs $byosnap_sid --tag $image_tag --resources-path $resources_path
251
305
  ```
252
306
 
253
- #### 6. byosnap publish-image
307
+ #### 8. byosnap publish-image
254
308
 
255
309
  Publish a custom snap code image. This command executes, `build`, `push` and `upload-docs` one
256
310
  after the other.
@@ -276,7 +330,7 @@ snapctl byosnap publish-image $byosnap_sid --tag $image_tag --path $code_root_pa
276
330
  snapctl byosnap publish-image $byosnap_sid --tag $image_tag --skip-build
277
331
  ```
278
332
 
279
- #### 7. byosnap publish-version
333
+ #### 9. byosnap publish-version
280
334
 
281
335
  Publish a new version for your Snap. Only after your Snap version is published, you will be able
282
336
  to use your snap in your Snapend. This command should be run after `push` or `publish-image` commands.
@@ -291,40 +345,11 @@ snapctl byosnap publish-version --help
291
345
  # Publish a new image
292
346
  # $byosnap_sid = Snap ID for your snap
293
347
  # $image_tag = An image tag for your snap
294
- # $prefix = Prefix for your snap Eg: /v1
295
348
  # $version = Semantic version for your snap Eg: v0.0.1
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
298
- # Example:
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
301
- ```
302
-
303
- #### 8. byosnap sync
304
-
305
- This command is for development purposes. It allows developers to rapidly build, update and push their
306
- BYOSnap to a dev Snapend. Simply, make changes to your code locally, and then run this command to deploy
307
- your BYOSnap straight to your development Snapend.
308
-
309
- IMPORTANT: This command will only work for Dev Snapends. Additionally if the tag you are using in this
310
- command happens to be used by a staging or a production snapend then `sync` will not work. We do this to
311
- ensure that your staging and production BYOSnap images do not get impacted.
312
-
313
- ```
314
- # Help for the byosnap command
315
- snapctl byosnap sync --help
316
-
317
- # Publish a new image
318
- # $byosnap_sid = Snap ID for your snap
319
- # $code_root_path = Local code path where your Dockerfile is present
320
- # $resources_path = Optional path to the resources directory in your Snap. This ensures, you are not forced to put the Dockerfile, swagger.json and README.md in the root directory of your Snap.
321
- # $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.
322
- # $image_tag = An image tag for your snap. Note snapctl adds a timestamp, allowing you to use the same command.
323
- # $version = Semantic version for your snap Eg: v0.0.1
324
- # $snapend_id = Dev Snapend Id
349
+ # $byosnapProfilePath = Path to the snapser-byosnap-profile.json 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
325
350
  # Example:
326
- snapctl byosnap sync byosnap-jinks-flask --path /Users/DevName/Development/SnapserEngine/jinks_flask --tag my-first-image --version "v0.0.11" --snapend-id "jxmmfryo"
327
- snapctl byosnap sync $byosnap_sid --path $code_root_path --tag $image_tag --version $version --snapend-id $snapend_id
351
+ # snapctl byosnap publish-version byosnap-jinks-flask --tag my-first-image --version v0.0.1 --path /Users/DevName/Development/SnapserEngine/jinks_flask
352
+ snapctl byosnap publish-version $byosnap_sid --tag $image_tag --version $version --path $byosnapProfilePath
328
353
  ```
329
354
 
330
355
  ### BYO Game Server - Bring your own Game Server
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "snapctl"
3
- version = "0.43.0"
3
+ version = "0.43.2"
4
4
  description = "Snapser CLI Tool"
5
5
  authors = ["Ajinkya Apte <aj@snapser.com>"]
6
6
  readme = "README.md"
@@ -27,8 +27,8 @@ from snapctl.config.constants import HTTP_ERROR_SERVICE_VERSION_EXISTS, \
27
27
  SNAPCTL_BYOSNAP_PUBLISH_VERSION_ERROR, HTTP_ERROR_SERVICE_IN_USE, \
28
28
  SNAPCTL_BYOSNAP_UPDATE_VERSION_ERROR, SNAPCTL_BYOSNAP_UPDATE_VERSION_SERVICE_IN_USE_ERROR, \
29
29
  SNAPCTL_BYOSNAP_UPDATE_VERSION_TAG_ERROR, SNAPCTL_BYOSNAP_NOT_FOUND, \
30
- HTTP_ERROR_RESOURCE_NOT_FOUND
31
- from snapctl.utils.echo import info, warning
30
+ HTTP_ERROR_RESOURCE_NOT_FOUND, SNAPCTL_BYOSNAP_PUBLISH_ERROR
31
+ from snapctl.utils.echo import info, warning, success
32
32
  from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success, \
33
33
  check_dockerfile_architecture
34
34
 
@@ -40,10 +40,12 @@ class ByoSnap:
40
40
  ID_PREFIX = 'byosnap-'
41
41
  SUBCOMMANDS = [
42
42
  'create', 'publish-image', 'publish-version', 'upload-docs', 'update-version',
43
- 'sync'
43
+ 'publish', 'sync'
44
44
  ]
45
+ PROFILE_NAME = 'snapser-byosnap-profile.json'
45
46
  PLATFORMS = ['linux/arm64', 'linux/amd64']
46
- LANGUAGES = ['go', 'python', 'ruby', 'c#', 'c++', 'rust', 'java', 'node']
47
+ LANGUAGES = ['go', 'node', 'python', 'java', 'csharp', 'cpp', 'rust',
48
+ 'ruby', 'php', 'perl', 'clojure', 'lua', 'ts', 'js', 'kotlin', 'c']
47
49
  DEFAULT_BUILD_PLATFORM = 'linux/arm64'
48
50
  SID_CHARACTER_LIMIT = 47
49
51
  TAG_CHARACTER_LIMIT = 80
@@ -57,43 +59,44 @@ class ByoSnap:
57
59
  name: Union[str, None] = None, desc: Union[str, None] = None,
58
60
  platform_type: Union[str, None] = None, language: Union[str, None] = None,
59
61
  tag: Union[str, None] = None, path: Union[str, None] = None,
60
- resources_path: Union[str, None] = None, dockerfile: Union[str, None] = None,
61
- prefix: Union[str, None] = None, version: Union[str, None] = None,
62
- http_port: Union[int, None] = None,
63
- byosnap_profile: Union[str, None] = None, skip_build: bool = False,
64
- readiness_path: Union[str, None] = None, readiness_delay: Union[int, None] = None,
65
- snapend_id: Union[str, None] = None, blocking: bool = False
62
+ resources_path: Union[str, None] = None, docker_file: Union[str, None] = None,
63
+ version: Union[str, None] = None, skip_build: bool = False,
64
+ snapend_id: Union[str, None] = None, blocking: bool = False,
65
+ byosnap_profile_file: Union[str, None] = None
66
66
  ) -> None:
67
+ # Set the BASE variables
67
68
  self.subcommand: str = subcommand
68
69
  self.base_url: str = base_url
69
70
  self.api_key: Union[str, None] = api_key
70
71
  self.sid: str = sid
71
- self.name: str = name
72
- self.desc: str = desc
73
- self.platform_type: str = platform_type
74
- self.language: str = language
75
- if subcommand != 'create':
76
- self.token: Union[str, None] = get_composite_token(
77
- base_url, api_key,
78
- 'byosnap', {'service_id': sid}
79
- )
80
- else:
81
- self.token: Union[str, None] = None
82
- self.token_parts: Union[list, None] = ByoSnap._get_token_values(
83
- self.token) if self.token is not None else None
72
+ self.token: Union[str, None] = None
73
+ self.token_parts: Union[list, None] = None
74
+ self.byosnap_profile: Union[str, None] = None
75
+ if subcommand not in ['create', 'publish']:
76
+ # Create does not need the token
77
+ # Publish handles this in the publish-image subcommand
78
+ self._setup_token_and_token_parts(base_url, api_key, sid)
84
79
  self.tag: Union[str, None] = tag
85
80
  self.path: Union[str, None] = path
86
81
  self.resources_path: Union[str, None] = resources_path
87
- self.dockerfile: str = dockerfile
88
- self.prefix: str = prefix
82
+ self.docker_file: str = docker_file
83
+ self.byosnap_profile_file: Union[str, None] = byosnap_profile_file
89
84
  self.version: Union[str, None] = version
90
- self.http_port: Union[int, None] = http_port
91
- self.byosnap_profile: Union[str, None] = byosnap_profile
92
- self.skip_build: bool = skip_build
93
- self.readiness_path: Union[str, None] = readiness_path
94
- self.readiness_delay: Union[int, None] = readiness_delay
85
+ self.name: Union[str, None] = name
86
+ self.desc: Union[str, None] = desc
87
+ self.platform_type: Union[str, None] = platform_type
88
+ self.language: Union[str, None] = language
95
89
  self.snapend_id: Union[str, None] = snapend_id
90
+ self.skip_build: bool = skip_build
96
91
  self.blocking: bool = blocking
92
+ # Override
93
+ self.prefix: Union[str, None] = None
94
+ self.ingress_external_port: Union[dict, None] = None
95
+ self.ingress_internal_ports: Union[list, None] = None
96
+ self.readiness_path: Union[str, None] = None
97
+ self.readiness_delay: Union[str, None] = None
98
+ if self.subcommand in ['publish', 'publish-version']:
99
+ self._validate_and_override_properties_from_profile()
97
100
  # Validate the input
98
101
  self.validate_input()
99
102
 
@@ -120,6 +123,206 @@ class ByoSnap:
120
123
  pass
121
124
  return None
122
125
 
126
+ def _setup_token_and_token_parts(self, base_url, api_key, sid) -> None:
127
+ '''
128
+ Setup the token and token parts for publishing and syncing
129
+ '''
130
+ self.token: Union[str, None] = get_composite_token(
131
+ base_url, api_key,
132
+ 'byosnap', {'service_id': sid}
133
+ )
134
+ self.token_parts: Union[list, None] = ByoSnap._get_token_values(
135
+ self.token) if self.token is not None else None
136
+
137
+ def _check_and_get_byosnap_profile(self) -> object:
138
+ """
139
+ Validate the BYOSnap profile
140
+ """
141
+ profile_data = None
142
+ with open(self.byosnap_profile, 'rb') as file:
143
+ try:
144
+ profile_data = json.load(file)
145
+ except json.JSONDecodeError:
146
+ pass
147
+ if not profile_data:
148
+ snapctl_error(
149
+ message='Invalid BYOSnap profile JSON. Please check the JSON structure',
150
+ code=SNAPCTL_INPUT_ERROR
151
+ )
152
+ if 'dev_template' not in profile_data or \
153
+ 'stage_template' not in profile_data or \
154
+ 'prod_template' not in profile_data:
155
+ snapctl_error(
156
+ message='Invalid BYOSnap profile JSON. Please check the JSON structure',
157
+ code=SNAPCTL_INPUT_ERROR
158
+ )
159
+ for profile in ['dev_template', 'stage_template', 'prod_template']:
160
+ # Currently, not checking for 'min_replicas' not in profile_data[profile]
161
+ if 'cpu' not in profile_data[profile] or \
162
+ 'memory' not in profile_data[profile] or \
163
+ 'cmd' not in profile_data[profile] or \
164
+ 'args' not in profile_data[profile] or \
165
+ 'env_params' not in profile_data[profile]:
166
+ snapctl_error(
167
+ message='Invalid BYOSnap profile JSON. Please check the JSON structure',
168
+ code=SNAPCTL_INPUT_ERROR
169
+ )
170
+ if profile_data[profile]['cpu'] not in ByoSnap.VALID_CPU_MARKS:
171
+ snapctl_error(
172
+ message='Invalid CPU value in BYOSnap profile. Valid values are' +
173
+ f'{", ".join(map(str, ByoSnap.VALID_CPU_MARKS))}',
174
+ code=SNAPCTL_INPUT_ERROR
175
+ )
176
+ if profile_data[profile]['memory'] not in ByoSnap.VALID_MEMORY_MARKS:
177
+ snapctl_error(
178
+ message='Invalid Memory value in BYOSnap profile. Valid values are ' +
179
+ f'{", ".join(map(str, ByoSnap.VALID_MEMORY_MARKS))}',
180
+ code=SNAPCTL_INPUT_ERROR
181
+ )
182
+ if 'min_replicas' in profile_data[profile] and \
183
+ (not isinstance(profile_data[profile]['min_replicas'], int) or
184
+ int(profile_data[profile]['min_replicas']) < 0 or
185
+ int(profile_data[profile]['min_replicas']) > ByoSnap.MAX_MIN_REPLICAS):
186
+ snapctl_error(
187
+ message='Invalid Min Replicas value in BYOSnap profile. ' +
188
+ 'Minimum replicas should be between 0 and ' +
189
+ f'{ByoSnap.MAX_MIN_REPLICAS}',
190
+ code=SNAPCTL_INPUT_ERROR
191
+ )
192
+ if 'name' not in profile_data or 'description' not in profile_data or \
193
+ 'platform' not in profile_data or 'language' not in profile_data or \
194
+ 'prefix' not in profile_data or \
195
+ ('http_port' not in profile_data and 'ingress' not in profile_data) or \
196
+ 'readiness_probe_config' not in profile_data or \
197
+ 'initial_delay_seconds' not in profile_data['readiness_probe_config'] or \
198
+ 'path' not in profile_data['readiness_probe_config']:
199
+ snapctl_error(
200
+ message='BYOSnap profile now requires name, description, platform, ' +
201
+ 'language, prefix, ingress, and readiness_probe_config fields. ' +
202
+ 'Please use the following command: ' +
203
+ '`snapctl generate profile --category byosnap --out-path $output_path` ' +
204
+ 'to generate a new profile',
205
+ code=SNAPCTL_INPUT_ERROR
206
+ )
207
+ return profile_data
208
+
209
+ def _validate_and_override_properties_from_profile(self) -> None:
210
+ # Build your snap
211
+ if self.resources_path:
212
+ base_path = self.resources_path
213
+ else:
214
+ base_path = self.path
215
+ if not self.byosnap_profile_file:
216
+ self.byosnap_profile_file = ByoSnap.PROFILE_NAME
217
+ self.byosnap_profile = os.path.join(
218
+ base_path, self.byosnap_profile_file)
219
+ if not os.path.isfile(self.byosnap_profile):
220
+ snapctl_error(
221
+ "Unable to find " +
222
+ f"{self.byosnap_profile_file} at path {base_path}",
223
+ SNAPCTL_INPUT_ERROR)
224
+ info('Extracting information from BYOSnap profile at path ' +
225
+ f'{self.byosnap_profile}')
226
+ profile_data = self._check_and_get_byosnap_profile()
227
+ self.name = profile_data['name']
228
+ self.desc = profile_data['description']
229
+ self.platform_type = profile_data['platform']
230
+ self.language = profile_data['language']
231
+ self.prefix = profile_data['prefix']
232
+ # Setup the final ingress external port
233
+ final_ingress_external_port = {
234
+ 'name': 'http',
235
+ 'port': None
236
+ }
237
+ if 'http_port' in profile_data:
238
+ final_ingress_external_port = {
239
+ 'name': 'http',
240
+ 'port': profile_data['http_port']
241
+ }
242
+ warning('http_port is deprecated. Please use ingress.external_port. ' +
243
+ 'You can generate a new BYOSnap profile via the `generate` command.')
244
+ elif 'ingress' in profile_data and 'external_port' in profile_data['ingress']:
245
+ final_ingress_external_port = profile_data['ingress']['external_port']
246
+ self.ingress_external_port = final_ingress_external_port
247
+ # Setup the final ingress internal ports
248
+ final_ingress_internal_ports = []
249
+ if 'ingress' in profile_data and 'internal_ports' in profile_data['ingress']:
250
+ final_ingress_internal_ports = profile_data['ingress']['internal_ports']
251
+ self.ingress_internal_ports = final_ingress_internal_ports
252
+ self.readiness_path = profile_data['readiness_probe_config']['path']
253
+ self.readiness_delay = \
254
+ profile_data['readiness_probe_config']['initial_delay_seconds']
255
+ # Validate
256
+ if not self.prefix or self.prefix == '':
257
+ snapctl_error("Missing prefix", SNAPCTL_INPUT_ERROR)
258
+ if not self.prefix.startswith('/'):
259
+ snapctl_error("Prefix should start with a forward slash (/)",
260
+ SNAPCTL_INPUT_ERROR)
261
+ if self.prefix.endswith('/'):
262
+ snapctl_error("Prefix should not end with a forward slash (/)",
263
+ SNAPCTL_INPUT_ERROR)
264
+ if not self.version:
265
+ snapctl_error("Missing version", SNAPCTL_INPUT_ERROR)
266
+ pattern = r'^v\d+\.\d+\.\d+$'
267
+ if not re.match(pattern, self.version):
268
+ snapctl_error("Version should be in the format vX.X.X",
269
+ SNAPCTL_INPUT_ERROR)
270
+ if not self.ingress_external_port['port']:
271
+ snapctl_error("Missing Ingress HTTP Port",
272
+ SNAPCTL_INPUT_ERROR)
273
+ if not isinstance(self.ingress_external_port['port'], int):
274
+ snapctl_error("Ingress external port should be a number",
275
+ SNAPCTL_INPUT_ERROR)
276
+ # Check internal ports
277
+ duplicate_name = {}
278
+ duplicate_port = {}
279
+ index = 0
280
+ for internal_port in self.ingress_internal_ports:
281
+ if 'name' not in internal_port or 'port' not in internal_port:
282
+ snapctl_error("Internal ports need a name and a port. Check internal port " +
283
+ f"number {index}.",
284
+ SNAPCTL_INPUT_ERROR)
285
+ # Confirm the name does not collide with the external port
286
+ if internal_port['name'] == self.ingress_external_port['name']:
287
+ snapctl_error("Internal port name should not be the same as " +
288
+ "the external port name", SNAPCTL_INPUT_ERROR)
289
+ # Confirm the port does not collide with the external port
290
+ if internal_port['port'] == self.ingress_external_port['port']:
291
+ snapctl_error("Internal port number should not be the same as " +
292
+ "the external port number", SNAPCTL_INPUT_ERROR)
293
+ index += 1
294
+ if not internal_port['port']:
295
+ snapctl_error("Missing internal port. Check internal port " +
296
+ f"number {index}",
297
+ SNAPCTL_INPUT_ERROR)
298
+ if not isinstance(internal_port['port'], int):
299
+ snapctl_error("Internal port should be a number. Check internal port " +
300
+ f"number {index}",
301
+ SNAPCTL_INPUT_ERROR)
302
+ if internal_port['name'] in duplicate_name:
303
+ snapctl_error("Duplicate internal port name. Check internal port " +
304
+ f"number {index}",
305
+ SNAPCTL_INPUT_ERROR)
306
+ if internal_port['port'] in duplicate_port:
307
+ snapctl_error("Duplicate internal port number. Check internal port " +
308
+ f"number {index}",
309
+ SNAPCTL_INPUT_ERROR)
310
+ duplicate_name[internal_port['name']] = True
311
+ duplicate_port[internal_port['port']] = True
312
+ if self.readiness_path is not None:
313
+ if self.readiness_path.strip() == '':
314
+ snapctl_error("Readiness path cannot be empty",
315
+ SNAPCTL_INPUT_ERROR)
316
+ if not self.readiness_path.strip().startswith('/'):
317
+ snapctl_error("Readiness path has to start with /",
318
+ SNAPCTL_INPUT_ERROR)
319
+ if self.readiness_delay is not None:
320
+ if self.readiness_delay < 0 or \
321
+ self.readiness_delay > ByoSnap.MAX_READINESS_TIMEOUT:
322
+ snapctl_error(
323
+ "Readiness delay should be between 0 " +
324
+ f"and {ByoSnap.MAX_READINESS_TIMEOUT}", SNAPCTL_INPUT_ERROR)
325
+
123
326
  def _check_dependencies(self) -> None:
124
327
  """
125
328
  Check application dependencies
@@ -212,7 +415,7 @@ class ByoSnap:
212
415
  base_path = self.resources_path
213
416
  else:
214
417
  base_path = self.path
215
- docker_file_path = os.path.join(base_path, self.dockerfile)
418
+ docker_file_path = os.path.join(base_path, self.docker_file)
216
419
 
217
420
  # Warning check for architecture specific commands
218
421
  info(f'Building on system architecture {sys_platform.machine()}')
@@ -324,71 +527,6 @@ class ByoSnap:
324
527
  message='BYOSnap upload failure. Duplicate image error.',
325
528
  code=SNAPCTL_BYOSNAP_PUBLISH_IMAGE_DUPLICATE_TAG_ERROR, progress=progress)
326
529
 
327
- def _validate_byosnap_profile(self) -> None:
328
- """
329
- Validate the BYOSnap profile
330
- """
331
- if not self.byosnap_profile:
332
- snapctl_error(
333
- message="Missing BYOSnap profile path", code=SNAPCTL_INPUT_ERROR)
334
- if not os.path.isfile(self.byosnap_profile):
335
- snapctl_error(
336
- message="Unable to find BYOSnap profile " +
337
- f"JSON at path {self.byosnap_profile}",
338
- code=SNAPCTL_INPUT_ERROR
339
- )
340
- profile_data = None
341
- with open(self.byosnap_profile, 'rb') as file:
342
- try:
343
- profile_data = json.load(file)
344
- except json.JSONDecodeError:
345
- pass
346
- if not profile_data:
347
- snapctl_error(
348
- message='Invalid BYOSnap profile JSON. Please check the JSON structure',
349
- code=SNAPCTL_INPUT_ERROR
350
- )
351
- if 'dev_template' not in profile_data or \
352
- 'stage_template' not in profile_data or \
353
- 'prod_template' not in profile_data:
354
- snapctl_error(
355
- message='Invalid BYOSnap profile JSON. Please check the JSON structure',
356
- code=SNAPCTL_INPUT_ERROR
357
- )
358
- for profile in ['dev_template', 'stage_template', 'prod_template']:
359
- # Currently, not checking for 'min_replicas' not in profile_data[profile]
360
- if 'cpu' not in profile_data[profile] or \
361
- 'memory' not in profile_data[profile] or \
362
- 'cmd' not in profile_data[profile] or \
363
- 'args' not in profile_data[profile] or \
364
- 'env_params' not in profile_data[profile]:
365
- snapctl_error(
366
- message='Invalid BYOSnap profile JSON. Please check the JSON structure',
367
- code=SNAPCTL_INPUT_ERROR
368
- )
369
- if profile_data[profile]['cpu'] not in ByoSnap.VALID_CPU_MARKS:
370
- snapctl_error(
371
- message='Invalid CPU value in BYOSnap profile. Valid values are' +
372
- f'{", ".join(map(str, ByoSnap.VALID_CPU_MARKS))}',
373
- code=SNAPCTL_INPUT_ERROR
374
- )
375
- if profile_data[profile]['memory'] not in ByoSnap.VALID_MEMORY_MARKS:
376
- snapctl_error(
377
- message='Invalid Memory value in BYOSnap profile. Valid values are ' +
378
- f'{", ".join(map(str, ByoSnap.VALID_MEMORY_MARKS))}',
379
- code=SNAPCTL_INPUT_ERROR
380
- )
381
- if 'min_replicas' in profile_data[profile] and \
382
- (not isinstance(profile_data[profile]['min_replicas'], int) or
383
- int(profile_data[profile]['min_replicas']) < 0 or
384
- int(profile_data[profile]['min_replicas']) > ByoSnap.MAX_MIN_REPLICAS):
385
- snapctl_error(
386
- message='Invalid Min Replicas value in BYOSnap profile. ' +
387
- 'Minimum replicas should be between 0 and ' +
388
- f'{ByoSnap.MAX_MIN_REPLICAS}',
389
- code=SNAPCTL_INPUT_ERROR
390
- )
391
-
392
530
  def _clean_slate(self) -> None:
393
531
  progress = Progress(
394
532
  SpinnerColumn(),
@@ -467,12 +605,10 @@ class ByoSnap:
467
605
  f"{', '.join(ByoSnap.PLATFORMS)}.",
468
606
  code=SNAPCTL_INPUT_ERROR
469
607
  )
470
- return
471
- # Now validate all other commands Check the token
472
- if self.token_parts is None:
473
- snapctl_error('Invalid token. Please reach out to your support team.',
474
- SNAPCTL_INPUT_ERROR)
475
- if self.subcommand in ['publish-image']:
608
+ elif self.subcommand == 'publish-image':
609
+ if self.token_parts is None:
610
+ snapctl_error('Invalid token. Please reach out to your support team.',
611
+ SNAPCTL_INPUT_ERROR)
476
612
  if not self.tag:
477
613
  snapctl_error(
478
614
  "Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
@@ -489,23 +625,25 @@ class ByoSnap:
489
625
  # Check path
490
626
  if self.resources_path:
491
627
  docker_file_path = \
492
- f"{self.resources_path}/{self.dockerfile}"
628
+ f"{self.resources_path}/{self.docker_file}"
493
629
  else:
494
- docker_file_path = f"{self.path}/{self.dockerfile}"
630
+ docker_file_path = f"{self.path}/{self.docker_file}"
495
631
  if not self.skip_build and not os.path.isfile(docker_file_path):
496
632
  snapctl_error(
497
633
  "Unable to find " +
498
- f"{self.dockerfile} at path {docker_file_path}",
634
+ f"{self.docker_file} at path {docker_file_path}",
499
635
  SNAPCTL_INPUT_ERROR)
500
- # elif self.subcommand == 'push':
501
- # if not self.tag:
502
- # error("Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
503
- # raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
504
636
  elif self.subcommand == 'upload-docs':
637
+ if self.token_parts is None:
638
+ snapctl_error('Invalid token. Please reach out to your support team.',
639
+ SNAPCTL_INPUT_ERROR)
505
640
  if self.path is None and self.resources_path is None:
506
641
  snapctl_error(
507
642
  "Missing one of: path or resources-path parameter", SNAPCTL_INPUT_ERROR)
508
643
  elif self.subcommand == 'publish-version':
644
+ if self.token_parts is None:
645
+ snapctl_error('Invalid token. Please reach out to your support team.',
646
+ SNAPCTL_INPUT_ERROR)
509
647
  if not self.tag:
510
648
  snapctl_error(
511
649
  "Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
@@ -516,42 +654,10 @@ class ByoSnap:
516
654
  f"{ByoSnap.TAG_CHARACTER_LIMIT} characters",
517
655
  SNAPCTL_INPUT_ERROR
518
656
  )
519
- if not self.prefix or self.prefix == '':
520
- snapctl_error("Missing prefix", SNAPCTL_INPUT_ERROR)
521
- if not self.prefix.startswith('/'):
522
- snapctl_error("Prefix should start with a forward slash (/)",
523
- SNAPCTL_INPUT_ERROR)
524
- if self.prefix.endswith('/'):
525
- snapctl_error("Prefix should not end with a forward slash (/)",
526
- SNAPCTL_INPUT_ERROR)
527
- if not self.version:
528
- snapctl_error("Missing version", SNAPCTL_INPUT_ERROR)
529
- pattern = r'^v\d+\.\d+\.\d+$'
530
- if not re.match(pattern, self.version):
531
- snapctl_error("Version should be in the format vX.X.X",
532
- SNAPCTL_INPUT_ERROR)
533
- if not self.http_port:
534
- snapctl_error("Missing Ingress HTTP Port",
535
- SNAPCTL_INPUT_ERROR)
536
- if not self.http_port.isdigit():
537
- snapctl_error("Ingress HTTP Port should be a number",
538
- SNAPCTL_INPUT_ERROR)
539
- if self.readiness_path is not None:
540
- if self.readiness_path.strip() == '':
541
- snapctl_error("Readiness path cannot be empty",
542
- SNAPCTL_INPUT_ERROR)
543
- if not self.readiness_path.strip().startswith('/'):
544
- snapctl_error("Readiness path has to start with /",
545
- SNAPCTL_INPUT_ERROR)
546
- if self.readiness_delay is not None:
547
- if self.readiness_delay < 0 or \
548
- self.readiness_delay > ByoSnap.MAX_READINESS_TIMEOUT:
549
- snapctl_error(
550
- "Readiness delay should be between 0 " +
551
- f"and {ByoSnap.MAX_READINESS_TIMEOUT}", SNAPCTL_INPUT_ERROR)
552
- # Check byosnap_profile path
553
- self._validate_byosnap_profile()
554
657
  elif self.subcommand == 'update-version':
658
+ if self.token_parts is None:
659
+ snapctl_error('Invalid token. Please reach out to your support team.',
660
+ SNAPCTL_INPUT_ERROR)
555
661
  if not self.version:
556
662
  snapctl_error(message="Missing version",
557
663
  code=SNAPCTL_INPUT_ERROR)
@@ -571,23 +677,39 @@ class ByoSnap:
571
677
  code=SNAPCTL_INPUT_ERROR
572
678
  )
573
679
  elif self.subcommand == 'sync':
680
+ if self.token_parts is None:
681
+ snapctl_error('Invalid token. Please reach out to your support team.',
682
+ SNAPCTL_INPUT_ERROR)
574
683
  if not self.version:
575
- snapctl_error(message="Missing version",
684
+ snapctl_error(message="Missing version. Version should be in the format vX.X.X",
576
685
  code=SNAPCTL_INPUT_ERROR)
577
686
  pattern = r'^v\d+\.\d+\.\d+$'
578
687
  if not re.match(pattern, self.version):
579
688
  snapctl_error(message="Version should be in the format vX.X.X",
580
689
  code=SNAPCTL_INPUT_ERROR)
581
- if not self.tag:
690
+ if not self.skip_build and not self.path:
582
691
  snapctl_error(
583
- message="Missing required parameter: tag", code=SNAPCTL_INPUT_ERROR)
584
- if len(self.tag.split()) > 1 or \
585
- len(self.tag) > ByoSnap.TAG_CHARACTER_LIMIT:
692
+ message="Missing required parameter: path",
693
+ code=SNAPCTL_INPUT_ERROR)
694
+ # Check path
695
+ if self.resources_path:
696
+ docker_file_path = \
697
+ f"{self.resources_path}/{self.docker_file}"
698
+ else:
699
+ docker_file_path = f"{self.path}/{self.docker_file}"
700
+ if not self.skip_build and not os.path.isfile(docker_file_path):
586
701
  snapctl_error(
587
- message="Tag should be a single word with maximum of " +
588
- f"{ByoSnap.TAG_CHARACTER_LIMIT} characters",
589
- code=SNAPCTL_INPUT_ERROR
590
- )
702
+ message="Unable to find " +
703
+ f"{self.docker_file} at path {docker_file_path}",
704
+ code=SNAPCTL_INPUT_ERROR)
705
+ elif self.subcommand == 'publish':
706
+ if not self.version:
707
+ snapctl_error(message="Missing version. Version should be in the format vX.X.X",
708
+ code=SNAPCTL_INPUT_ERROR)
709
+ pattern = r'^v\d+\.\d+\.\d+$'
710
+ if not re.match(pattern, self.version):
711
+ snapctl_error(message="Version should be in the format vX.X.X",
712
+ code=SNAPCTL_INPUT_ERROR)
591
713
  if not self.skip_build and not self.path:
592
714
  snapctl_error(
593
715
  message="Missing required parameter: path",
@@ -595,15 +717,16 @@ class ByoSnap:
595
717
  # Check path
596
718
  if self.resources_path:
597
719
  docker_file_path = \
598
- f"{self.resources_path}/{self.dockerfile}"
720
+ f"{self.resources_path}/{self.docker_file}"
599
721
  else:
600
- docker_file_path = f"{self.path}/{self.dockerfile}"
722
+ docker_file_path = f"{self.path}/{self.docker_file}"
601
723
  if not self.skip_build and not os.path.isfile(docker_file_path):
602
724
  snapctl_error(
603
725
  message="Unable to find " +
604
- f"{self.dockerfile} at path {docker_file_path}",
726
+ f"{self.docker_file} at path {docker_file_path}",
605
727
  code=SNAPCTL_INPUT_ERROR)
606
- # CRUD methods
728
+
729
+ # Basic methods
607
730
 
608
731
  def build(self) -> None:
609
732
  """
@@ -629,7 +752,7 @@ class ByoSnap:
629
752
  self._docker_login()
630
753
  self._docker_push()
631
754
 
632
- # Upper echelon commands
755
+ # Crud methods
633
756
  def upload_docs(self, no_exit: bool = False) -> None:
634
757
  '''
635
758
  Note this step is optional hence we do not raise a typer.Exit
@@ -852,14 +975,19 @@ class ByoSnap:
852
975
  "version": self.version,
853
976
  "image_tag": self.tag,
854
977
  "base_url": f"{self.prefix}/{self.sid}",
855
- "http_port": self.http_port,
978
+ "ingress": {
979
+ "external_port": self.ingress_external_port,
980
+ "internal_ports": self.ingress_internal_ports
981
+ },
856
982
  "readiness_probe_config": {
857
983
  "path": self.readiness_path,
858
984
  "initial_delay_seconds": self.readiness_delay
859
985
  },
860
986
  "dev_template": profile_data['dev_template'],
861
987
  "stage_template": profile_data['stage_template'],
862
- "prod_template": profile_data['prod_template']
988
+ "prod_template": profile_data['prod_template'],
989
+ # Currently not supported so we are just hardcoding an empty list
990
+ "egress": {"ports": []},
863
991
  }
864
992
  res = requests.post(
865
993
  f"{self.base_url}/v1/snapser-api/byosnaps/{self.sid}/versions",
@@ -959,12 +1087,57 @@ class ByoSnap:
959
1087
  message='Failed to update version',
960
1088
  code=SNAPCTL_BYOSNAP_UPDATE_VERSION_ERROR, progress=progress)
961
1089
 
1090
+ # Upper echelon methods
1091
+ def publish(self) -> None:
1092
+ '''
1093
+ Sync the snap
1094
+ '''
1095
+ try:
1096
+ # Attempt to create a BYOSnap but no worries if it fails
1097
+ payload = {
1098
+ "service_id": self.sid,
1099
+ "name": self.name,
1100
+ "description": self.desc,
1101
+ "platform": self.platform_type,
1102
+ "language": self.language,
1103
+ }
1104
+ res = requests.post(
1105
+ f"{self.base_url}/v1/snapser-api/byosnaps",
1106
+ json=payload, headers={'api-key': self.api_key},
1107
+ timeout=SERVER_CALL_TIMEOUT
1108
+ )
1109
+ if res.ok:
1110
+ success('BYOSnap created successfully')
1111
+ else:
1112
+ response_json = res.json()
1113
+ if "api_error_code" in response_json and "message" in response_json:
1114
+ if response_json['api_error_code'] == HTTP_ERROR_SERVICE_VERSION_EXISTS:
1115
+ info(
1116
+ msg=f'BYOSnap {self.name} present. ' +
1117
+ 'Lets proceed',
1118
+ )
1119
+ # Make the tag same as version
1120
+ self.tag = self.version
1121
+ # Setup the token and token parts
1122
+ self._setup_token_and_token_parts(
1123
+ self.base_url, self.api_key, self.sid)
1124
+ # Now publish the image
1125
+ self.publish_image(no_exit=True)
1126
+ # Now publish the version
1127
+ self.publish_version(no_exit=True)
1128
+ return snapctl_success(message='BYOSNAP published successfully')
1129
+ except RequestException as e:
1130
+ snapctl_error(
1131
+ message='Exception: Unable to publish a ' +
1132
+ f' version for your Byosnap. Exception: {e}',
1133
+ code=SNAPCTL_BYOSNAP_PUBLISH_ERROR)
1134
+
962
1135
  def sync(self) -> None:
963
1136
  '''
964
1137
  Sync the snap
965
1138
  '''
966
1139
  try:
967
- self.tag = f'{self.tag}-{int(time.time())}'
1140
+ self.tag = f'{self.version}-{int(time.time())}'
968
1141
  self.publish_image(no_exit=True)
969
1142
  self.update_version(no_exit=True)
970
1143
  byosnap_list: str = f"{self.sid}:{self.version}"
@@ -2,7 +2,7 @@
2
2
  Constants used by snapctl
3
3
  """
4
4
  COMPANY_NAME = 'Snapser'
5
- VERSION = '0.43.0'
5
+ VERSION = '0.43.2'
6
6
  CONFIG_FILE_MAC = '~/.snapser/config'
7
7
  CONFIG_FILE_WIN = '%homepath%\\.snapser\\config'
8
8
 
@@ -69,6 +69,7 @@ SNAPCTL_BYOSNAP_UPDATE_VERSION_ERROR = 45
69
69
  SNAPCTL_BYOSNAP_UPDATE_VERSION_SERVICE_IN_USE_ERROR = 46
70
70
  SNAPCTL_BYOSNAP_UPDATE_VERSION_TAG_ERROR = 47
71
71
  SNAPCTL_BYOSNAP_UPDATE_VERSION_INVALID_VERSION_ERROR = 48
72
+ SNAPCTL_BYOSNAP_PUBLISH_ERROR = 49
72
73
 
73
74
  # Game Errors
74
75
  SNAPCTL_GAME_NOT_FOUND = SNAPCTL_RESOURCE_NOT_FOUND
@@ -188,6 +188,25 @@ DEFAULT_BYOSNAP_PROD_TEMPLATE: Dict[str, object] = {
188
188
  }
189
189
 
190
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
+ },
191
210
  'dev_template': DEFAULT_BYOSNAP_DEV_TEMPLATE,
192
211
  'stage_template': DEFAULT_BYOSNAP_STAGE_TEMPLATE,
193
212
  'prod_template': DEFAULT_BYOSNAP_PROD_TEMPLATE
@@ -317,6 +317,30 @@ def byosnap(
317
317
  ..., help="BYOSnap Subcommands: " + ", ".join(ByoSnap.SUBCOMMANDS) + "."
318
318
  ),
319
319
  sid: str = typer.Argument(..., help="Snap Id. Should start with byosnap-"),
320
+ # publish
321
+ path: Union[str, None] = typer.Option(
322
+ None, "--path", help="(req: publish, sync, publish-image, publish-version) Path to your snap code"
323
+ ),
324
+ resources_path: Union[str, None] = typer.Option(
325
+ None, "--resources-path", help="(optional: publish, sync, publish-image, publish-version; req: upload-docs) Path to resources such as your Dockerfile, snapser-byosnap-profile.json, snapser-tool-*.json, swagger.json or README.md"
326
+ ),
327
+ # publish, sync and publish-version
328
+ version: Union[str, None] = typer.Option(
329
+ None, "--version",
330
+ help="(req: publish, sync, publish-version) Snap version. Should start with v. Example vX.X.X"
331
+ ),
332
+ # sync
333
+ snapend_id: str = typer.Option(
334
+ None, "--snapend-id",
335
+ help=("(req: sync) Snapend Id. NOTE: Development Snapends only.")
336
+ ),
337
+ blocking: bool = typer.Option(
338
+ False, "--blocking",
339
+ help=(
340
+ "(optional: sync) Set to true if you want to wait for the update to complete "
341
+ "before returning."
342
+ )
343
+ ),
320
344
  # create
321
345
  name: str = typer.Option(
322
346
  None, "--name", help="(req: create) Name for your snap."
@@ -337,62 +361,24 @@ def byosnap(
337
361
  # publish-image and publish-version
338
362
  tag: str = typer.Option(
339
363
  None, "--tag", help=(
340
- "(req: publish-image, publish-version, sync) Tag for your snap"
341
- )
342
- ),
343
- # publish-image
344
- path: Union[str, None] = typer.Option(
345
- None, "--path", help="(req: publish-image, sync) Path to your snap code"
346
- ),
347
- resources_path: Union[str, None] = typer.Option(
348
- None, "--resources-path", help="(optional: publish-image, sync; req: upload-docs) Path to resources such as your Dockerfile, swagger.json or README.md"
349
- ),
350
- docker_file: str = typer.Option(
351
- "Dockerfile", help="(optional: publish) Dockerfile name to use"
352
- ),
353
- # publish-version
354
- prefix: str = typer.Option(
355
- '/v1', "--prefix", help="(req: publish-version) URL Prefix for your snap"
356
- ),
357
- version: Union[str, None] = typer.Option(
358
- None, "--version",
359
- help="(req: publish-version) Snap version. Should start with v. Example vX.X.X"
360
- ),
361
- http_port: Union[str, None] = typer.Option(
362
- None, "--http-port", help="(req: publish-version) Ingress HTTP port version"
363
- ),
364
- byosnap_profile: Union[str, None] = typer.Option(
365
- None, "--byosnap-profile", help=(
366
- "(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."
364
+ "(req: publish-image, publish-version) Tag for your snap"
367
365
  )
368
366
  ),
367
+ # overrides
369
368
  skip_build: bool = typer.Option(
370
369
  False, "--skip-build", help="(optional: publish-image, sync) Skip the build step. You have to pass the image tag you used during the build step."
371
370
  ),
372
- readiness_path: str = typer.Option(
373
- None, "--readiness-path", help="(req: publish-version) Readiness path for your snap"
374
- ),
375
- readiness_delay: int = typer.Option(
376
- None, "--readiness-delay", help="(req: publish-version) Delay before readiness check"
377
- ),
378
- # sync
379
- snapend_id: str = typer.Option(
380
- None, "--snapend-id",
381
- help=("(req: sync) Snapend Id. NOTE: Development Snapends only.")
371
+ docker_file: str = typer.Option(
372
+ "Dockerfile", help="(optional override: publish, sync) Dockerfile name to use"
382
373
  ),
383
- blocking: bool = typer.Option(
384
- False, "--blocking",
385
- help=(
386
- "(optional: sync) Set to true if you want to wait for the update to complete "
387
- "before returning."
388
- )
374
+ byosnap_profile_file: str = typer.Option(
375
+ "snapser-byosnap-profile.json", "--byosnap-profile-file", help="(optional override: publish, publish-version) BYOSnap Profile file name to use"
389
376
  ),
390
- # overrides
391
377
  api_key: Union[str, None] = typer.Option(
392
- None, "--api-key", help="API Key override.", callback=api_key_context_callback
378
+ None, "--api-key", help="(optional override) API Key override.", callback=api_key_context_callback
393
379
  ),
394
380
  profile: Union[str, None] = typer.Option(
395
- None, "--profile", help="Profile to use.", callback=profile_context_callback
381
+ None, "--profile", help="(optional override) Profile to use.", callback=profile_context_callback
396
382
  ),
397
383
  ) -> None:
398
384
  """
@@ -411,16 +397,12 @@ def byosnap(
411
397
  tag=tag,
412
398
  path=path,
413
399
  resources_path=resources_path,
414
- dockerfile=docker_file,
415
- prefix=prefix,
400
+ docker_file=docker_file,
416
401
  version=version,
417
- http_port=http_port,
418
- byosnap_profile=byosnap_profile,
419
402
  skip_build=skip_build,
420
- readiness_path=readiness_path,
421
- readiness_delay=readiness_delay,
422
403
  snapend_id=snapend_id,
423
- blocking=blocking
404
+ blocking=blocking,
405
+ byosnap_profile_file=byosnap_profile_file
424
406
  )
425
407
  getattr(byosnap_obj, subcommand.replace('-', '_'))()
426
408
  success(f"BYOSnap {subcommand} complete")
@@ -71,7 +71,7 @@ def get_composite_token(base_url: str, api_key: Union[str, None], action: str, p
71
71
  else:
72
72
  error(f'Failed to validate API Key. Error: {res.text}')
73
73
  raise typer.Exit(code=SNAPCTL_CONFIGURATION_ERROR)
74
- success('API Key validated')
74
+ success('Generate snapctl transaction token')
75
75
  return res.json()['token']
76
76
 
77
77
 
File without changes
File without changes
File without changes
File without changes