nextmv 1.0.0.dev3__py3-none-any.whl → 1.0.0.dev4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nextmv/__about__.py +1 -1
- nextmv/cli/CONTRIBUTING.md +81 -29
- nextmv/cli/cloud/acceptance/create.py +20 -22
- nextmv/cli/cloud/acceptance/delete.py +7 -8
- nextmv/cli/cloud/acceptance/get.py +9 -10
- nextmv/cli/cloud/acceptance/list.py +3 -3
- nextmv/cli/cloud/acceptance/update.py +6 -6
- nextmv/cli/cloud/account/__init__.py +3 -3
- nextmv/cli/cloud/account/create.py +11 -11
- nextmv/cli/cloud/account/delete.py +6 -7
- nextmv/cli/cloud/account/get.py +3 -3
- nextmv/cli/cloud/account/update.py +5 -5
- nextmv/cli/cloud/app/create.py +25 -26
- nextmv/cli/cloud/app/delete.py +5 -6
- nextmv/cli/cloud/app/exists.py +2 -2
- nextmv/cli/cloud/app/get.py +2 -2
- nextmv/cli/cloud/app/list.py +3 -3
- nextmv/cli/cloud/app/push.py +269 -45
- nextmv/cli/cloud/app/update.py +12 -12
- nextmv/cli/cloud/batch/create.py +26 -28
- nextmv/cli/cloud/batch/delete.py +5 -6
- nextmv/cli/cloud/batch/get.py +8 -8
- nextmv/cli/cloud/batch/list.py +3 -3
- nextmv/cli/cloud/batch/metadata.py +4 -4
- nextmv/cli/cloud/batch/update.py +6 -6
- nextmv/cli/cloud/data/__init__.py +1 -1
- nextmv/cli/cloud/data/upload.py +15 -15
- nextmv/cli/cloud/ensemble/__init__.py +2 -0
- nextmv/cli/cloud/ensemble/create.py +21 -22
- nextmv/cli/cloud/ensemble/delete.py +5 -6
- nextmv/cli/cloud/ensemble/get.py +4 -4
- nextmv/cli/cloud/ensemble/list.py +63 -0
- nextmv/cli/cloud/ensemble/update.py +9 -9
- nextmv/cli/cloud/input_set/create.py +20 -22
- nextmv/cli/cloud/input_set/get.py +3 -3
- nextmv/cli/cloud/input_set/list.py +3 -3
- nextmv/cli/cloud/input_set/update.py +24 -24
- nextmv/cli/cloud/instance/create.py +14 -15
- nextmv/cli/cloud/instance/delete.py +5 -6
- nextmv/cli/cloud/instance/exists.py +2 -2
- nextmv/cli/cloud/instance/get.py +2 -2
- nextmv/cli/cloud/instance/list.py +3 -3
- nextmv/cli/cloud/instance/update.py +14 -14
- nextmv/cli/cloud/managed_input/create.py +14 -16
- nextmv/cli/cloud/managed_input/delete.py +6 -7
- nextmv/cli/cloud/managed_input/get.py +3 -3
- nextmv/cli/cloud/managed_input/list.py +3 -3
- nextmv/cli/cloud/managed_input/update.py +9 -9
- nextmv/cli/cloud/run/cancel.py +2 -2
- nextmv/cli/cloud/run/create.py +32 -33
- nextmv/cli/cloud/run/get.py +8 -8
- nextmv/cli/cloud/run/input.py +4 -4
- nextmv/cli/cloud/run/list.py +6 -6
- nextmv/cli/cloud/run/logs.py +9 -10
- nextmv/cli/cloud/run/metadata.py +4 -4
- nextmv/cli/cloud/run/track.py +32 -33
- nextmv/cli/cloud/scenario/create.py +21 -21
- nextmv/cli/cloud/scenario/delete.py +5 -6
- nextmv/cli/cloud/scenario/get.py +8 -8
- nextmv/cli/cloud/scenario/list.py +3 -3
- nextmv/cli/cloud/scenario/metadata.py +4 -4
- nextmv/cli/cloud/scenario/update.py +6 -6
- nextmv/cli/cloud/secrets/create.py +17 -17
- nextmv/cli/cloud/secrets/delete.py +5 -6
- nextmv/cli/cloud/secrets/get.py +4 -4
- nextmv/cli/cloud/secrets/list.py +3 -3
- nextmv/cli/cloud/secrets/update.py +17 -20
- nextmv/cli/cloud/shadow/create.py +31 -31
- nextmv/cli/cloud/shadow/delete.py +5 -6
- nextmv/cli/cloud/shadow/get.py +2 -2
- nextmv/cli/cloud/shadow/list.py +3 -3
- nextmv/cli/cloud/shadow/metadata.py +4 -4
- nextmv/cli/cloud/shadow/start.py +3 -3
- nextmv/cli/cloud/shadow/stop.py +4 -6
- nextmv/cli/cloud/shadow/update.py +6 -6
- nextmv/cli/cloud/switchback/create.py +19 -15
- nextmv/cli/cloud/switchback/delete.py +5 -6
- nextmv/cli/cloud/switchback/get.py +3 -3
- nextmv/cli/cloud/switchback/list.py +3 -3
- nextmv/cli/cloud/switchback/metadata.py +6 -6
- nextmv/cli/cloud/switchback/start.py +4 -4
- nextmv/cli/cloud/switchback/stop.py +4 -6
- nextmv/cli/cloud/switchback/update.py +6 -6
- nextmv/cli/cloud/upload/create.py +2 -2
- nextmv/cli/cloud/version/create.py +9 -10
- nextmv/cli/cloud/version/delete.py +5 -6
- nextmv/cli/cloud/version/exists.py +2 -2
- nextmv/cli/cloud/version/get.py +2 -2
- nextmv/cli/cloud/version/list.py +3 -3
- nextmv/cli/cloud/version/update.py +8 -8
- nextmv/cli/community/clone.py +12 -10
- nextmv/cli/community/list.py +9 -9
- nextmv/cli/configuration/config.py +43 -10
- nextmv/cli/configuration/create.py +3 -3
- nextmv/cli/configuration/delete.py +7 -7
- nextmv/cli/configuration/list.py +3 -3
- nextmv/cli/confirm.py +32 -0
- nextmv/cli/main.py +27 -36
- nextmv/cli/message.py +2 -2
- nextmv/cli/version.py +1 -1
- nextmv/cloud/application/__init__.py +190 -54
- nextmv/cloud/application/_batch_scenario.py +2 -2
- nextmv/cloud/application/_instance.py +2 -2
- nextmv/cloud/application/_managed_input.py +1 -1
- nextmv/cloud/application/_shadow.py +1 -1
- nextmv/cloud/application/_switchback.py +11 -3
- nextmv/cloud/application/_version.py +3 -2
- nextmv/cloud/shadow.py +43 -4
- nextmv/cloud/switchback.py +46 -9
- {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/METADATA +1 -1
- nextmv-1.0.0.dev4.dist-info/RECORD +183 -0
- nextmv-1.0.0.dev3.dist-info/RECORD +0 -181
- {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/WHEEL +0 -0
- {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/entry_points.txt +0 -0
- {nextmv-1.0.0.dev3.dist-info → nextmv-1.0.0.dev4.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,9 +5,9 @@ This module defines the cloud scenario delete command for the Nextmv CLI.
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
8
|
|
|
10
9
|
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
11
|
from nextmv.cli.message import info, success
|
|
12
12
|
from nextmv.cli.options import AppIDOption, ProfileOption, ScenarioTestIDOption
|
|
13
13
|
|
|
@@ -33,24 +33,23 @@ def delete(
|
|
|
33
33
|
Deletes a Nextmv Cloud scenario test.
|
|
34
34
|
|
|
35
35
|
This action is permanent and cannot be undone. The scenario test and all
|
|
36
|
-
associated data will be deleted. Use the
|
|
36
|
+
associated data will be deleted. Use the --yes flag to skip
|
|
37
37
|
the confirmation prompt.
|
|
38
38
|
|
|
39
39
|
[bold][underline]Examples[/underline][/bold]
|
|
40
40
|
|
|
41
41
|
- Delete the scenario test with the ID [magenta]hop-analysis[/magenta] from application
|
|
42
42
|
[magenta]hare-app[/magenta].
|
|
43
|
-
$ [
|
|
43
|
+
$ [dim]nextmv cloud scenario delete --app-id hare-app --scenario-test-id hop-analysis[/dim]
|
|
44
44
|
|
|
45
45
|
- Delete the scenario test without confirmation prompt.
|
|
46
|
-
$ [
|
|
46
|
+
$ [dim]nextmv cloud scenario delete --app-id hare-app --scenario-test-id carrot-routes --yes[/dim]
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
if not yes:
|
|
50
|
-
confirm =
|
|
50
|
+
confirm = get_confirmation(
|
|
51
51
|
f"Are you sure you want to delete scenario test [magenta]{scenario_test_id}[/magenta] "
|
|
52
52
|
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
53
|
-
default=False,
|
|
54
53
|
)
|
|
55
54
|
|
|
56
55
|
if not confirm:
|
nextmv/cli/cloud/scenario/get.py
CHANGED
|
@@ -42,7 +42,7 @@ def get(
|
|
|
42
42
|
"--wait",
|
|
43
43
|
"-w",
|
|
44
44
|
help="Wait for the scenario test to complete. Results are printed to [magenta]stdout[/magenta]. "
|
|
45
|
-
"Specify output location with
|
|
45
|
+
"Specify output location with --output.",
|
|
46
46
|
),
|
|
47
47
|
] = False,
|
|
48
48
|
profile: ProfileOption = None,
|
|
@@ -50,8 +50,8 @@ def get(
|
|
|
50
50
|
"""
|
|
51
51
|
Get a Nextmv Cloud scenario test, including its runs.
|
|
52
52
|
|
|
53
|
-
Use the
|
|
54
|
-
complete, polling for results. Using the
|
|
53
|
+
Use the --wait flag to wait for the scenario test to
|
|
54
|
+
complete, polling for results. Using the --output flag will
|
|
55
55
|
also activate waiting, and allows you to specify a destination file for the
|
|
56
56
|
results.
|
|
57
57
|
|
|
@@ -59,17 +59,17 @@ def get(
|
|
|
59
59
|
|
|
60
60
|
- Get the scenario test with ID [magenta]carrot-optimization[/magenta] from application
|
|
61
61
|
[magenta]hare-app[/magenta].
|
|
62
|
-
$ [
|
|
62
|
+
$ [dim]nextmv cloud scenario get --app-id hare-app --scenario-test-id carrot-optimization[/dim]
|
|
63
63
|
|
|
64
64
|
- Get the scenario test and wait for it to complete if necessary.
|
|
65
|
-
$ [
|
|
65
|
+
$ [dim]nextmv cloud scenario get --app-id hare-app --scenario-test-id bunny-hop-test --wait[/dim]
|
|
66
66
|
|
|
67
67
|
- Get the scenario test and save the results to a file.
|
|
68
|
-
$ [
|
|
69
|
-
--output results.json[/
|
|
68
|
+
$ [dim]nextmv cloud scenario get --app-id hare-app --scenario-test-id warren-planning \\
|
|
69
|
+
--output results.json[/dim]
|
|
70
70
|
|
|
71
71
|
- Get the scenario test using a specific profile.
|
|
72
|
-
$ [
|
|
72
|
+
$ [dim]nextmv cloud scenario get --app-id hare-app --scenario-test-id lettuce-routes --profile prod[/dim]
|
|
73
73
|
"""
|
|
74
74
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
75
75
|
|
|
@@ -38,13 +38,13 @@ def list(
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- List all scenario tests for application [magenta]hare-app[/magenta].
|
|
41
|
-
$ [
|
|
41
|
+
$ [dim]nextmv cloud scenario list --app-id hare-app[/dim]
|
|
42
42
|
|
|
43
43
|
- List all scenario tests and save to a file.
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud scenario list --app-id hare-app --output scenario_tests.json[/dim]
|
|
45
45
|
|
|
46
46
|
- List all scenario tests using a specific profile.
|
|
47
|
-
$ [
|
|
47
|
+
$ [dim]nextmv cloud scenario list --app-id hare-app --profile prod[/dim]
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -41,14 +41,14 @@ def metadata(
|
|
|
41
41
|
|
|
42
42
|
- Get metadata for scenario test [magenta]bunny-warren-optimization[/magenta] from application
|
|
43
43
|
[magenta]hare-app[/magenta].
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud scenario metadata --app-id hare-app --scenario-test-id bunny-warren-optimization[/dim]
|
|
45
45
|
|
|
46
46
|
- Get metadata and save to a file.
|
|
47
|
-
$ [
|
|
48
|
-
--output metadata.json[/
|
|
47
|
+
$ [dim]nextmv cloud scenario metadata --app-id hare-app --scenario-test-id lettuce-delivery \\
|
|
48
|
+
--output metadata.json[/dim]
|
|
49
49
|
|
|
50
50
|
- Get metadata using a specific profile.
|
|
51
|
-
$ [
|
|
51
|
+
$ [dim]nextmv cloud scenario metadata --app-id hare-app --scenario-test-id hop-schedule --profile prod[/dim]
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -57,17 +57,17 @@ def update(
|
|
|
57
57
|
[bold][underline]Examples[/underline][/bold]
|
|
58
58
|
|
|
59
59
|
- Update the name of a scenario test.
|
|
60
|
-
$ [
|
|
61
|
-
--name "Spring Carrot Harvest"[/
|
|
60
|
+
$ [dim]nextmv cloud scenario update --app-id hare-app --scenario-test-id carrot-feast \\
|
|
61
|
+
--name "Spring Carrot Harvest"[/dim]
|
|
62
62
|
|
|
63
63
|
- Update the description of a scenario test.
|
|
64
|
-
$ [
|
|
65
|
-
--description "Optimizing hop paths through the meadow"[/
|
|
64
|
+
$ [dim]nextmv cloud scenario update --app-id hare-app --scenario-test-id bunny-hop-routes \\
|
|
65
|
+
--description "Optimizing hop paths through the meadow"[/dim]
|
|
66
66
|
|
|
67
67
|
- Update both name and description and save the result.
|
|
68
|
-
$ [
|
|
68
|
+
$ [dim]nextmv cloud scenario update --app-id hare-app --scenario-test-id lettuce-delivery \\
|
|
69
69
|
--name "Warren Lettuce Express" --description "Fast lettuce delivery to all burrows" \\
|
|
70
|
-
--output updated-scenario.json[/
|
|
70
|
+
--output updated-scenario.json[/dim]
|
|
71
71
|
"""
|
|
72
72
|
|
|
73
73
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -27,7 +27,7 @@ def create(
|
|
|
27
27
|
"Pass multiple secrets by repeating the flag, or providing a list of objects. "
|
|
28
28
|
"Allowed values for [magenta]type[/magenta] are: "
|
|
29
29
|
f"{enum_values(SecretType)}. "
|
|
30
|
-
"Object format: [
|
|
30
|
+
"Object format: [dim]{'type': type, 'location': location, 'value': value}[/dim].",
|
|
31
31
|
metavar="SECRETS",
|
|
32
32
|
),
|
|
33
33
|
],
|
|
@@ -67,7 +67,7 @@ def create(
|
|
|
67
67
|
A secrets collection is a group of key-value pairs that can be used by
|
|
68
68
|
your application instances during execution. Each collection can contain
|
|
69
69
|
up to 20 secrets. Secrets are provided as JSON objects using the
|
|
70
|
-
|
|
70
|
+
--secrets flag.
|
|
71
71
|
|
|
72
72
|
Each secret must include three fields:
|
|
73
73
|
- [magenta]type[/magenta]: Either [magenta]env[/magenta] or [magenta]file[/magenta],
|
|
@@ -80,43 +80,43 @@ def create(
|
|
|
80
80
|
|
|
81
81
|
You can provide secrets in three ways:
|
|
82
82
|
- A single secret as a [magenta]json[/magenta] object.
|
|
83
|
-
- Multiple secrets by repeating the
|
|
84
|
-
- Multiple secrets as a [magenta]json[/magenta] array in a single
|
|
83
|
+
- Multiple secrets by repeating the --secrets flag.
|
|
84
|
+
- Multiple secrets as a [magenta]json[/magenta] array in a single --secrets flag.
|
|
85
85
|
|
|
86
|
-
The
|
|
86
|
+
The --secrets-collection-id and --name are optional.
|
|
87
87
|
If not provided, they will be automatically generated.
|
|
88
88
|
|
|
89
89
|
[bold][underline]Examples[/underline][/bold]
|
|
90
90
|
|
|
91
91
|
- Create a secrets collection with a single environment variable secret.
|
|
92
|
-
$ [
|
|
93
|
-
--secrets '{"type": "env", "location": "API_KEY", "value": "secret-value"}'[/
|
|
92
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
93
|
+
--secrets '{"type": "env", "location": "API_KEY", "value": "secret-value"}'[/dim]
|
|
94
94
|
|
|
95
95
|
- Create a secrets collection with multiple secrets by repeating the flag.
|
|
96
|
-
$ [
|
|
96
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
97
97
|
--secrets '{"type": "env", "location": "API_KEY", "value": "secret-value"}' \\
|
|
98
|
-
--secrets '{"type": "env", "location": "DATABASE_URL", "value": "postgres://localhost"}'[/
|
|
98
|
+
--secrets '{"type": "env", "location": "DATABASE_URL", "value": "postgres://localhost"}'[/dim]
|
|
99
99
|
|
|
100
100
|
- Create a secrets collection with multiple secrets in a single JSON array.
|
|
101
|
-
$ [
|
|
102
|
-
--secrets '[{"type": "env", "location": "DB_USER", "value": "admin"}, {...}]'[/
|
|
101
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
102
|
+
--secrets '[{"type": "env", "location": "DB_USER", "value": "admin"}, {...}]'[/dim]
|
|
103
103
|
|
|
104
104
|
- Create a secrets collection with custom ID, name, and description.
|
|
105
|
-
$ [
|
|
105
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
106
106
|
--secrets-collection-id db-creds --name "Database Credentials" \\
|
|
107
107
|
--description "Production database credentials" \\
|
|
108
108
|
--secrets '{"type": "env", "location": "DB_USER", "value": "admin"}' \\
|
|
109
|
-
--secrets '{"type": "env", "location": "DB_PASS", "value": "secure123"}'[/
|
|
109
|
+
--secrets '{"type": "env", "location": "DB_PASS", "value": "secure123"}'[/dim]
|
|
110
110
|
|
|
111
111
|
- Create a secrets collection with file-based secrets.
|
|
112
|
-
$ [
|
|
112
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
113
113
|
--secrets-collection-id certs --name "Certificates" \\
|
|
114
|
-
--secrets '{"type": "file", "location": "licenses/acme.lic", "value": "LICENSE_CONTENT_HERE"}'[/
|
|
114
|
+
--secrets '{"type": "file", "location": "licenses/acme.lic", "value": "LICENSE_CONTENT_HERE"}'[/dim]
|
|
115
115
|
|
|
116
116
|
- Mix environment and file-based secrets.
|
|
117
|
-
$ [
|
|
117
|
+
$ [dim]nextmv cloud secrets create --app-id hare-app \\
|
|
118
118
|
--secrets '{"type": "env", "location": "ACME_LICENSE_KEY", "value": "abc123"}' \\
|
|
119
|
-
--secrets '{"type": "file", "location": "config/app.conf", "value": "server=prod\\nport=8080"}'[/
|
|
119
|
+
--secrets '{"type": "file", "location": "config/app.conf", "value": "server=prod\\nport=8080"}'[/dim]
|
|
120
120
|
"""
|
|
121
121
|
|
|
122
122
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -5,9 +5,9 @@ This module defines the cloud secrets delete command for the Nextmv CLI.
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
8
|
|
|
10
9
|
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
11
|
from nextmv.cli.message import info, success
|
|
12
12
|
from nextmv.cli.options import AppIDOption, ProfileOption, SecretsCollectionIDOption
|
|
13
13
|
|
|
@@ -32,24 +32,23 @@ def delete(
|
|
|
32
32
|
"""
|
|
33
33
|
Deletes a Nextmv Cloud secrets collection.
|
|
34
34
|
|
|
35
|
-
This action is permanent and cannot be undone. Use the
|
|
35
|
+
This action is permanent and cannot be undone. Use the --yes
|
|
36
36
|
flag to skip the confirmation prompt.
|
|
37
37
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- Delete the secrets collection with the ID [magenta]api-keys[/magenta] from application
|
|
41
41
|
[magenta]hare-app[/magenta].
|
|
42
|
-
$ [
|
|
42
|
+
$ [dim]nextmv cloud secrets delete --app-id hare-app --secrets-collection-id api-keys[/dim]
|
|
43
43
|
|
|
44
44
|
- Delete the secrets collection without confirmation prompt.
|
|
45
|
-
$ [
|
|
45
|
+
$ [dim]nextmv cloud secrets delete --app-id hare-app --secrets-collection-id api-keys --yes[/dim]
|
|
46
46
|
"""
|
|
47
47
|
|
|
48
48
|
if not yes:
|
|
49
|
-
confirm =
|
|
49
|
+
confirm = get_confirmation(
|
|
50
50
|
f"Are you sure you want to delete secrets collection [magenta]{secrets_collection_id}[/magenta] "
|
|
51
51
|
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
52
|
-
default=False,
|
|
53
52
|
)
|
|
54
53
|
|
|
55
54
|
if not confirm:
|
nextmv/cli/cloud/secrets/get.py
CHANGED
|
@@ -41,13 +41,13 @@ def get(
|
|
|
41
41
|
|
|
42
42
|
- Get the secrets collection with the ID [magenta]api-keys[/magenta] from
|
|
43
43
|
application [magenta]hare-app[/magenta].
|
|
44
|
-
$ [
|
|
45
|
-
--secrets-collection-id api-keys[/
|
|
44
|
+
$ [dim]nextmv cloud secrets get --app-id hare-app \\
|
|
45
|
+
--secrets-collection-id api-keys[/dim]
|
|
46
46
|
|
|
47
47
|
- Get the secrets collection with the ID [magenta]api-keys[/magenta] and
|
|
48
48
|
save the information to a [magenta]secrets.json[/magenta] file.
|
|
49
|
-
$ [
|
|
50
|
-
--secrets-collection-id api-keys --output secrets.json[/
|
|
49
|
+
$ [dim]nextmv cloud secrets get --app-id hare-app \\
|
|
50
|
+
--secrets-collection-id api-keys --output secrets.json[/dim]
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/secrets/list.py
CHANGED
|
@@ -35,13 +35,13 @@ def list(
|
|
|
35
35
|
[bold][underline]Examples[/underline][/bold]
|
|
36
36
|
|
|
37
37
|
- List all secrets collections of application [magenta]hare-app[/magenta].
|
|
38
|
-
$ [
|
|
38
|
+
$ [dim]nextmv cloud secrets list --app-id hare-app[/dim]
|
|
39
39
|
|
|
40
40
|
- List all secrets collections using the profile named [magenta]hare[/magenta].
|
|
41
|
-
$ [
|
|
41
|
+
$ [dim]nextmv cloud secrets list --app-id hare-app --profile hare[/dim]
|
|
42
42
|
|
|
43
43
|
- List all secrets collections and save the information to a [magenta]secrets.json[/magenta] file.
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud secrets list --app-id hare-app --output secrets.json[/dim]
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
47
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -57,7 +57,7 @@ def update(
|
|
|
57
57
|
"Pass multiple secrets by repeating the flag, or providing a list of objects. "
|
|
58
58
|
"Allowed values for [magenta]type[/magenta] are: "
|
|
59
59
|
f"{enum_values(SecretType)}. "
|
|
60
|
-
"Object format: [
|
|
60
|
+
"Object format: [dim]{'type': type, 'location': location, 'value': value}[/dim]. "
|
|
61
61
|
"This will replace all existing secrets in the collection.",
|
|
62
62
|
metavar="SECRETS",
|
|
63
63
|
),
|
|
@@ -71,52 +71,49 @@ def update(
|
|
|
71
71
|
secrets collection. When updating secrets, all existing secrets will be
|
|
72
72
|
replaced with the new ones provided.
|
|
73
73
|
|
|
74
|
-
Secrets are provided as JSON objects using the
|
|
74
|
+
Secrets are provided as JSON objects using the --secrets flag,
|
|
75
75
|
following the same format as the create command. You can provide secrets as:
|
|
76
76
|
- A single secret as a JSON object
|
|
77
|
-
- Multiple secrets by repeating the
|
|
78
|
-
- Multiple secrets as a JSON array in a single
|
|
77
|
+
- Multiple secrets by repeating the --secrets flag
|
|
78
|
+
- Multiple secrets as a JSON array in a single --secrets flag
|
|
79
79
|
|
|
80
80
|
[bold][underline]Examples[/underline][/bold]
|
|
81
81
|
|
|
82
82
|
- Update the name of a secrets collection.
|
|
83
|
-
$ [
|
|
84
|
-
--secrets-collection-id api-keys --name "Updated API Keys"[/
|
|
83
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
84
|
+
--secrets-collection-id api-keys --name "Updated API Keys"[/dim]
|
|
85
85
|
|
|
86
86
|
- Update the description of a secrets collection.
|
|
87
|
-
$ [
|
|
87
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
88
88
|
--secrets-collection-id api-keys \\
|
|
89
|
-
--description "Updated collection of API keys"[/
|
|
89
|
+
--description "Updated collection of API keys"[/dim]
|
|
90
90
|
|
|
91
91
|
- Update both name and description.
|
|
92
|
-
$ [
|
|
92
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
93
93
|
--secrets-collection-id api-keys --name "Production API Keys" \\
|
|
94
|
-
--description "API keys for production environment"[/
|
|
94
|
+
--description "API keys for production environment"[/dim]
|
|
95
95
|
|
|
96
96
|
- Replace all secrets in a collection with new secrets.
|
|
97
|
-
$ [
|
|
97
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
98
98
|
--secrets-collection-id api-keys \\
|
|
99
99
|
--secrets '{"type": "env", "location": "API_KEY", "value": "new-value"}' \\
|
|
100
|
-
--secrets '{"type": "env", "location": "DATABASE_URL", "value": "postgres://newhost"}'[/
|
|
100
|
+
--secrets '{"type": "env", "location": "DATABASE_URL", "value": "postgres://newhost"}'[/dim]
|
|
101
101
|
|
|
102
102
|
- Replace all secrets with a JSON array.
|
|
103
|
-
$ [
|
|
103
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
104
104
|
--secrets-collection-id api-keys \\
|
|
105
|
-
--secrets '[{"type": "env", "location": "API_KEY", "value": "new-value"}, {...}]'[/
|
|
105
|
+
--secrets '[{"type": "env", "location": "API_KEY", "value": "new-value"}, {...}]'[/dim]
|
|
106
106
|
|
|
107
107
|
- Update multiple attributes at once and save the result.
|
|
108
|
-
$ [
|
|
108
|
+
$ [dim]nextmv cloud secrets update --app-id hare-app \\
|
|
109
109
|
--secrets-collection-id api-keys --name "New Name" \\
|
|
110
110
|
--description "New Description" \\
|
|
111
111
|
--secrets '{"type": "env", "location": "NEW_KEY", "value": "new-value"}' \\
|
|
112
|
-
--output updated.json[/
|
|
112
|
+
--output updated.json[/dim]
|
|
113
113
|
"""
|
|
114
114
|
|
|
115
115
|
if name is None and description is None and secrets is None:
|
|
116
|
-
error(
|
|
117
|
-
"Provide at least one option to update: "
|
|
118
|
-
"[code]--name[/code], [code]--description[/code], or [code]--secrets[/code]."
|
|
119
|
-
)
|
|
116
|
+
error("Provide at least one option to update: --name, --description, or --secrets.")
|
|
120
117
|
|
|
121
118
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
122
119
|
|
|
@@ -27,7 +27,7 @@ def create(
|
|
|
27
27
|
"-c",
|
|
28
28
|
help="Object mapping baseline instance IDs to a list of comparison instance IDs. "
|
|
29
29
|
"Data should be valid [magenta]json[/magenta]. "
|
|
30
|
-
"Object format: [
|
|
30
|
+
"Object format: [dim]{'baseline_id1': ['comparison_id1', 'comparison_id2'], 'baseline_id2': ...}[/dim]",
|
|
31
31
|
metavar="COMPARISONS",
|
|
32
32
|
),
|
|
33
33
|
],
|
|
@@ -36,8 +36,10 @@ def create(
|
|
|
36
36
|
typer.Option(
|
|
37
37
|
"--termination-maximum-runs",
|
|
38
38
|
"-m",
|
|
39
|
-
help="Maximum number of runs for the shadow test termination condition.
|
|
39
|
+
help="Maximum number of runs for the shadow test termination condition.",
|
|
40
40
|
metavar="TERMINATION_MAXIMUM_RUNS",
|
|
41
|
+
min=1,
|
|
42
|
+
max=300,
|
|
41
43
|
),
|
|
42
44
|
],
|
|
43
45
|
description: Annotated[
|
|
@@ -75,7 +77,7 @@ def create(
|
|
|
75
77
|
"-r",
|
|
76
78
|
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
77
79
|
help="Scheduled time for shadow test start in [magenta]RFC 3339[/magenta] format. "
|
|
78
|
-
"
|
|
80
|
+
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
79
81
|
metavar="START_TIME",
|
|
80
82
|
),
|
|
81
83
|
] = None,
|
|
@@ -85,7 +87,7 @@ def create(
|
|
|
85
87
|
"--termination-time",
|
|
86
88
|
"-t",
|
|
87
89
|
help="Scheduled time for shadow test end in [magenta]RFC 3339[/magenta] format. "
|
|
88
|
-
"
|
|
90
|
+
"Object format: [dim]'2024-01-01T00:00:00Z'[/dim]",
|
|
89
91
|
formats=["%Y-%m-%dT%H:%M:%S%z"],
|
|
90
92
|
metavar="TERMINATION_TIME",
|
|
91
93
|
),
|
|
@@ -95,42 +97,40 @@ def create(
|
|
|
95
97
|
"""
|
|
96
98
|
Create a new Nextmv Cloud shadow test in draft mode.
|
|
97
99
|
|
|
98
|
-
Use the
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
baseline.
|
|
100
|
+
Use the --comparisons option to define how to set up instance comparisons.
|
|
101
|
+
The value should be valid [magenta]json[/magenta]. The keys of the
|
|
102
|
+
comparisons object are the baseline instance IDs, and the values are the
|
|
103
|
+
candidate lists of instance IDs to compare against the respective baseline.
|
|
103
104
|
|
|
104
105
|
Here is an example comparisons object:
|
|
105
|
-
[
|
|
106
|
+
[dim]{
|
|
106
107
|
"baseline-instance-1": ["candidate-instance-1", "candidate-instance-2"],
|
|
107
108
|
"baseline-instance-2": ["candidate-instance-3"]
|
|
108
|
-
}[/
|
|
109
|
+
}[/dim]
|
|
109
110
|
|
|
110
|
-
You may specify the
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
You may specify the --start-time option to make the shadow test start at a
|
|
112
|
+
specific time. Alternatively, you may use the [code]nextmv cloud shadow
|
|
113
|
+
start[/code] command to start the test.
|
|
113
114
|
|
|
114
|
-
The
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
test.
|
|
115
|
+
The --termination-maximum-runs option is required and provides control over
|
|
116
|
+
when the shadow test should terminate, after said number of runs.
|
|
117
|
+
Alternatively, you may specify the --termination-time option or use the
|
|
118
|
+
[code]nextmv cloud shadow stop[/code] command to stop the test.
|
|
119
119
|
|
|
120
120
|
[bold][underline]Examples[/underline][/bold]
|
|
121
121
|
|
|
122
|
-
- Create a shadow test with a baseline and two candidate instances
|
|
123
|
-
$ [
|
|
122
|
+
- Create a shadow test with a baseline and two candidate instances.
|
|
123
|
+
$ [dim]COMPARISONS='{
|
|
124
124
|
"fluffy-bunny-baseline": [
|
|
125
125
|
"hopping-candidate-ears",
|
|
126
126
|
"speedy-cottontail"
|
|
127
127
|
]
|
|
128
128
|
}'
|
|
129
129
|
nextmv cloud shadow create --app-id hare-app --shadow-test-id bunny-hop-shadow --name "Bunny Hop Showdown" \\
|
|
130
|
-
--comparisons "$COMPARISONS" --termination-maximum-runs 100[/
|
|
130
|
+
--comparisons "$COMPARISONS" --termination-maximum-runs 100[/dim]
|
|
131
131
|
|
|
132
|
-
- Create a shadow test with multiple baselines and candidates
|
|
133
|
-
$ [
|
|
132
|
+
- Create a shadow test with multiple baselines and candidates.
|
|
133
|
+
$ [dim]COMPARISONS='{
|
|
134
134
|
"fluffy-bunny-baseline": [
|
|
135
135
|
"hopping-candidate-ears"
|
|
136
136
|
],
|
|
@@ -139,26 +139,26 @@ def create(
|
|
|
139
139
|
]
|
|
140
140
|
}'
|
|
141
141
|
nextmv cloud shadow create --app-id hare-app --shadow-test-id warren-race --name "Warren Race Test" \\
|
|
142
|
-
--comparisons "$COMPARISONS" --termination-maximum-runs 50[/
|
|
142
|
+
--comparisons "$COMPARISONS" --termination-maximum-runs 50[/dim]
|
|
143
143
|
|
|
144
|
-
- Create a shadow test with a scheduled start and termination time
|
|
145
|
-
$ [
|
|
144
|
+
- Create a shadow test with a scheduled start and termination time.
|
|
145
|
+
$ [dim]COMPARISONS='{
|
|
146
146
|
"fluffy-bunny-baseline": [
|
|
147
147
|
"hopping-candidate-ears"
|
|
148
148
|
]
|
|
149
149
|
}'
|
|
150
150
|
nextmv cloud shadow create --app-id hare-app --shadow-test-id sunrise-hop --name "Sunrise Hop Test" \\
|
|
151
151
|
--comparisons "$COMPARISONS" --start-time '2026-01-23T10:00:00Z' \\
|
|
152
|
-
--termination-time '2026-01-23T18:00:00Z' --termination-maximum-runs 20[/
|
|
152
|
+
--termination-time '2026-01-23T18:00:00Z' --termination-maximum-runs 20[/dim]
|
|
153
153
|
|
|
154
|
-
- Create a shadow test with a description
|
|
155
|
-
$ [
|
|
154
|
+
- Create a shadow test with a description.
|
|
155
|
+
$ [dim]COMPARISONS='{
|
|
156
156
|
"fluffy-bunny-baseline": [
|
|
157
157
|
"hopping-candidate-ears"
|
|
158
158
|
]
|
|
159
159
|
}'
|
|
160
160
|
nextmv cloud shadow create --app-id hare-app --shadow-test-id carrot-compare --name "Carrot Comparison" \\
|
|
161
|
-
--description "Testing cool bunnies" --comparisons "$COMPARISONS" --termination-maximum-runs 10[/
|
|
161
|
+
--description "Testing cool bunnies" --comparisons "$COMPARISONS" --termination-maximum-runs 10[/dim]
|
|
162
162
|
"""
|
|
163
163
|
|
|
164
164
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -5,9 +5,9 @@ This module defines the cloud shadow delete command for the Nextmv CLI.
|
|
|
5
5
|
from typing import Annotated
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
|
-
from rich.prompt import Confirm
|
|
9
8
|
|
|
10
9
|
from nextmv.cli.configuration.config import build_app
|
|
10
|
+
from nextmv.cli.confirm import get_confirmation
|
|
11
11
|
from nextmv.cli.message import info, success
|
|
12
12
|
from nextmv.cli.options import AppIDOption, ProfileOption, ShadowTestIDOption
|
|
13
13
|
|
|
@@ -33,24 +33,23 @@ def delete(
|
|
|
33
33
|
Deletes a Nextmv Cloud shadow test.
|
|
34
34
|
|
|
35
35
|
This action is permanent and cannot be undone. The shadow test and all
|
|
36
|
-
associated data, including runs, will be deleted. Use the
|
|
36
|
+
associated data, including runs, will be deleted. Use the --yes
|
|
37
37
|
flag to skip the confirmation prompt.
|
|
38
38
|
|
|
39
39
|
[bold][underline]Examples[/underline][/bold]
|
|
40
40
|
|
|
41
41
|
- Delete the shadow test with the ID [magenta]hop-analysis[/magenta] from application
|
|
42
42
|
[magenta]hare-app[/magenta].
|
|
43
|
-
$ [
|
|
43
|
+
$ [dim]nextmv cloud shadow delete --app-id hare-app --shadow-test-id hop-analysis[/dim]
|
|
44
44
|
|
|
45
45
|
- Delete the shadow test without confirmation prompt.
|
|
46
|
-
$ [
|
|
46
|
+
$ [dim]nextmv cloud shadow delete --app-id hare-app --shadow-test-id carrot-routes --yes[/dim]
|
|
47
47
|
"""
|
|
48
48
|
|
|
49
49
|
if not yes:
|
|
50
|
-
confirm =
|
|
50
|
+
confirm = get_confirmation(
|
|
51
51
|
f"Are you sure you want to delete shadow test [magenta]{shadow_test_id}[/magenta] "
|
|
52
52
|
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
53
|
-
default=False,
|
|
54
53
|
)
|
|
55
54
|
|
|
56
55
|
if not confirm:
|
nextmv/cli/cloud/shadow/get.py
CHANGED
|
@@ -37,10 +37,10 @@ def get(
|
|
|
37
37
|
|
|
38
38
|
- Get the shadow test with ID [magenta]carrot-optimization[/magenta] from application
|
|
39
39
|
[magenta]hare-app[/magenta].
|
|
40
|
-
$ [
|
|
40
|
+
$ [dim]nextmv cloud shadow get --app-id hare-app --shadow-test-id carrot-optimization[/dim]
|
|
41
41
|
|
|
42
42
|
- Get the shadow test using a specific profile.
|
|
43
|
-
$ [
|
|
43
|
+
$ [dim]nextmv cloud shadow get --app-id hare-app --shadow-test-id lettuce-routes --profile prod[/dim]
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/shadow/list.py
CHANGED
|
@@ -38,13 +38,13 @@ def list(
|
|
|
38
38
|
[bold][underline]Examples[/underline][/bold]
|
|
39
39
|
|
|
40
40
|
- List all shadow tests for application [magenta]hare-app[/magenta].
|
|
41
|
-
$ [
|
|
41
|
+
$ [dim]nextmv cloud shadow list --app-id hare-app[/dim]
|
|
42
42
|
|
|
43
43
|
- List all shadow tests and save to a file.
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud shadow list --app-id hare-app --output tests.json[/dim]
|
|
45
45
|
|
|
46
46
|
- List all shadow tests using a specific profile.
|
|
47
|
-
$ [
|
|
47
|
+
$ [dim]nextmv cloud shadow list --app-id hare-app --profile prod[/dim]
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
@@ -41,14 +41,14 @@ def metadata(
|
|
|
41
41
|
|
|
42
42
|
- Get metadata for shadow test [magenta]bunny-warren-optimization[/magenta] from application
|
|
43
43
|
[magenta]hare-app[/magenta].
|
|
44
|
-
$ [
|
|
44
|
+
$ [dim]nextmv cloud shadow metadata --app-id hare-app --shadow-test-id bunny-warren-optimization[/dim]
|
|
45
45
|
|
|
46
46
|
- Get metadata and save to a file.
|
|
47
|
-
$ [
|
|
48
|
-
--output metadata.json[/
|
|
47
|
+
$ [dim]nextmv cloud shadow metadata --app-id hare-app --shadow-test-id lettuce-delivery \\
|
|
48
|
+
--output metadata.json[/dim]
|
|
49
49
|
|
|
50
50
|
- Get metadata using a specific profile.
|
|
51
|
-
$ [
|
|
51
|
+
$ [dim]nextmv cloud shadow metadata --app-id hare-app --shadow-test-id hop-schedule --profile prod[/dim]
|
|
52
52
|
"""
|
|
53
53
|
|
|
54
54
|
cloud_app = build_app(app_id=app_id, profile=profile)
|
nextmv/cli/cloud/shadow/start.py
CHANGED
|
@@ -23,15 +23,15 @@ def start(
|
|
|
23
23
|
|
|
24
24
|
Before starting a shadow test, it must be created in draft state. You may
|
|
25
25
|
use the [code]nextmv cloud shadow create[/code] command to create a new
|
|
26
|
-
shadow test. Alternatively, define a
|
|
27
|
-
|
|
26
|
+
shadow test. Alternatively, define a --start-time when using the
|
|
27
|
+
[code]nextmv cloud shadow create[/code] command to have the shadow test
|
|
28
28
|
start automatically at a specific time.
|
|
29
29
|
|
|
30
30
|
[bold][underline]Examples[/underline][/bold]
|
|
31
31
|
|
|
32
32
|
- Start the shadow test with the ID [magenta]hop-analysis[/magenta] from application
|
|
33
33
|
[magenta]hare-app[/magenta].
|
|
34
|
-
$ [
|
|
34
|
+
$ [dim]nextmv cloud shadow start --app-id hare-app --shadow-test-id hop-analysis[/dim]
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
37
|
in_progress(msg="Starting shadow test...")
|