devnomads-cli 0.5.3__tar.gz → 0.5.5__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.
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/PKG-INFO +8 -3
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/README.md +7 -2
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/PKG-INFO +8 -3
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/dncli.py +132 -116
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/pyproject.toml +1 -1
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_cert.py +1 -1
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_cli.py +14 -24
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_generated_cli.py +8 -9
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_helpers.py +10 -10
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_transfer.py +1 -2
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/LICENSE +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/SOURCES.txt +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/dependency_links.txt +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/entry_points.txt +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/requires.txt +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/devnomads_cli.egg-info/top_level.txt +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/setup.cfg +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_config.py +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_generate.py +0 -0
- {devnomads_cli-0.5.3 → devnomads_cli-0.5.5}/tests/test_hook.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devnomads-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5
|
|
4
4
|
Summary: Manage your DevNomads services from the command line
|
|
5
5
|
Author-email: DevNomads <support@devnomads.nl>
|
|
6
6
|
License: MIT
|
|
@@ -111,11 +111,16 @@ export DN_PROFILE=acme
|
|
|
111
111
|
## Scripting
|
|
112
112
|
|
|
113
113
|
Output is a human-readable table on a terminal and JSON when piped,
|
|
114
|
-
so pipelines get parseable output without any flags; `--
|
|
115
|
-
|
|
114
|
+
so pipelines get parseable output without any flags; `--json` and
|
|
115
|
+
`--table` force either. Data goes to stdout, everything else
|
|
116
116
|
(warnings, prompts, status messages) to stderr, so `dncli ... | jq .`
|
|
117
117
|
is always safe.
|
|
118
118
|
|
|
119
|
+
List tables show a focused set of columns: fields that are empty for
|
|
120
|
+
every row, and nested collections (a server's IPs, a container's
|
|
121
|
+
instances, a mailbox list) are left out of the overview. Use `<group>
|
|
122
|
+
show <id>` or `--json` for the complete record.
|
|
123
|
+
|
|
119
124
|
In CI and pipelines, skip the credentials file and pass the key via
|
|
120
125
|
the environment:
|
|
121
126
|
|
|
@@ -95,11 +95,16 @@ export DN_PROFILE=acme
|
|
|
95
95
|
## Scripting
|
|
96
96
|
|
|
97
97
|
Output is a human-readable table on a terminal and JSON when piped,
|
|
98
|
-
so pipelines get parseable output without any flags; `--
|
|
99
|
-
|
|
98
|
+
so pipelines get parseable output without any flags; `--json` and
|
|
99
|
+
`--table` force either. Data goes to stdout, everything else
|
|
100
100
|
(warnings, prompts, status messages) to stderr, so `dncli ... | jq .`
|
|
101
101
|
is always safe.
|
|
102
102
|
|
|
103
|
+
List tables show a focused set of columns: fields that are empty for
|
|
104
|
+
every row, and nested collections (a server's IPs, a container's
|
|
105
|
+
instances, a mailbox list) are left out of the overview. Use `<group>
|
|
106
|
+
show <id>` or `--json` for the complete record.
|
|
107
|
+
|
|
103
108
|
In CI and pipelines, skip the credentials file and pass the key via
|
|
104
109
|
the environment:
|
|
105
110
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devnomads-cli
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5
|
|
4
4
|
Summary: Manage your DevNomads services from the command line
|
|
5
5
|
Author-email: DevNomads <support@devnomads.nl>
|
|
6
6
|
License: MIT
|
|
@@ -111,11 +111,16 @@ export DN_PROFILE=acme
|
|
|
111
111
|
## Scripting
|
|
112
112
|
|
|
113
113
|
Output is a human-readable table on a terminal and JSON when piped,
|
|
114
|
-
so pipelines get parseable output without any flags; `--
|
|
115
|
-
|
|
114
|
+
so pipelines get parseable output without any flags; `--json` and
|
|
115
|
+
`--table` force either. Data goes to stdout, everything else
|
|
116
116
|
(warnings, prompts, status messages) to stderr, so `dncli ... | jq .`
|
|
117
117
|
is always safe.
|
|
118
118
|
|
|
119
|
+
List tables show a focused set of columns: fields that are empty for
|
|
120
|
+
every row, and nested collections (a server's IPs, a container's
|
|
121
|
+
instances, a mailbox list) are left out of the overview. Use `<group>
|
|
122
|
+
show <id>` or `--json` for the complete record.
|
|
123
|
+
|
|
119
124
|
In CI and pipelines, skip the credentials file and pass the key via
|
|
120
125
|
the environment:
|
|
121
126
|
|
|
@@ -176,13 +176,25 @@ class AppState:
|
|
|
176
176
|
client: DevNomadsClient | None = None
|
|
177
177
|
|
|
178
178
|
|
|
179
|
-
def
|
|
179
|
+
def _format_flag(as_json: bool | None) -> OutputFormat | None:
|
|
180
|
+
"""Map the ``--json``/``--table`` flag to a format: True is JSON, False is
|
|
181
|
+
table, None means "not given - decide from the terminal"."""
|
|
182
|
+
|
|
183
|
+
if as_json is True:
|
|
184
|
+
return OutputFormat.json
|
|
185
|
+
if as_json is False:
|
|
186
|
+
return OutputFormat.table
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def state_from(ctx: typer.Context, output: bool | None = None) -> AppState:
|
|
180
191
|
state = ctx.obj
|
|
181
192
|
if not isinstance(state, AppState): # direct invocation in tests
|
|
182
193
|
state = AppState()
|
|
183
194
|
ctx.obj = state
|
|
184
|
-
|
|
185
|
-
|
|
195
|
+
fmt = _format_flag(output)
|
|
196
|
+
if fmt is not None: # per-command --json/--table overrides the global one
|
|
197
|
+
state.output = fmt
|
|
186
198
|
return state
|
|
187
199
|
|
|
188
200
|
|
|
@@ -342,14 +354,14 @@ def _render_kv(data: dict[str, Any], title: str | None) -> None:
|
|
|
342
354
|
def _auto_columns(rows: list[dict[str, Any]]) -> list[str]:
|
|
343
355
|
"""Choose the columns worth showing in a list view, from the data itself.
|
|
344
356
|
|
|
345
|
-
|
|
357
|
+
Two things get dropped, because a list is an overview and the full record
|
|
346
358
|
is always available via the matching ``show`` command (or ``-o json``):
|
|
347
359
|
|
|
348
360
|
* columns empty in every row (no information at all);
|
|
349
361
|
* columns holding a list of objects (instances, mailboxes, ips, ...) -
|
|
350
|
-
these are detail, belonging in the ``show`` view, not the overview
|
|
351
|
-
|
|
352
|
-
|
|
362
|
+
these are detail, belonging in the ``show`` view, not the overview.
|
|
363
|
+
|
|
364
|
+
Every other field is kept, even if its value is the same on every row.
|
|
353
365
|
"""
|
|
354
366
|
|
|
355
367
|
cols: list[str] = []
|
|
@@ -370,17 +382,11 @@ def _auto_columns(rows: list[dict[str, Any]]) -> list[str]:
|
|
|
370
382
|
for row in rows
|
|
371
383
|
)
|
|
372
384
|
|
|
373
|
-
|
|
385
|
+
return [
|
|
374
386
|
c
|
|
375
387
|
for c in cols
|
|
376
388
|
if any(not empty(row.get(c)) for row in rows) and not is_object_list(c)
|
|
377
389
|
]
|
|
378
|
-
if len(rows) > 1 and cols:
|
|
379
|
-
anchor = cols[0]
|
|
380
|
-
rendered = {c: {_cell(row.get(c)) for row in rows} for c in cols}
|
|
381
|
-
if any(len(values) > 1 for values in rendered.values()):
|
|
382
|
-
cols = [c for c in cols if c == anchor or len(rendered[c]) > 1]
|
|
383
|
-
return cols
|
|
384
390
|
|
|
385
391
|
|
|
386
392
|
def _render_rows(
|
|
@@ -1001,8 +1007,11 @@ SortOption = Annotated[
|
|
|
1001
1007
|
),
|
|
1002
1008
|
]
|
|
1003
1009
|
OutputOption = Annotated[
|
|
1004
|
-
|
|
1005
|
-
typer.Option(
|
|
1010
|
+
bool | None,
|
|
1011
|
+
typer.Option(
|
|
1012
|
+
"--json/--table",
|
|
1013
|
+
help="Force JSON or table output (default: table on a TTY, JSON piped).",
|
|
1014
|
+
),
|
|
1006
1015
|
]
|
|
1007
1016
|
|
|
1008
1017
|
|
|
@@ -1028,11 +1037,11 @@ def main(
|
|
|
1028
1037
|
),
|
|
1029
1038
|
] = None,
|
|
1030
1039
|
output: Annotated[
|
|
1031
|
-
|
|
1040
|
+
bool | None,
|
|
1032
1041
|
typer.Option(
|
|
1033
|
-
"--
|
|
1034
|
-
"
|
|
1035
|
-
|
|
1042
|
+
"--json/--table",
|
|
1043
|
+
help="Force JSON or table output; default: table on a TTY, "
|
|
1044
|
+
"JSON when piped.",
|
|
1036
1045
|
),
|
|
1037
1046
|
] = None,
|
|
1038
1047
|
debug: Annotated[
|
|
@@ -1048,7 +1057,12 @@ def main(
|
|
|
1048
1057
|
),
|
|
1049
1058
|
] = False,
|
|
1050
1059
|
) -> None:
|
|
1051
|
-
ctx.obj = AppState(
|
|
1060
|
+
ctx.obj = AppState(
|
|
1061
|
+
profile=profile,
|
|
1062
|
+
api_key=api_key,
|
|
1063
|
+
output=_format_flag(output),
|
|
1064
|
+
debug=debug,
|
|
1065
|
+
)
|
|
1052
1066
|
|
|
1053
1067
|
|
|
1054
1068
|
# --- configure -------------------------------------------------------------
|
|
@@ -2067,7 +2081,9 @@ _SORT_OPT = typer.Option(
|
|
|
2067
2081
|
)
|
|
2068
2082
|
_YES_OPT = typer.Option(False, "--yes", "-y", help="Do not ask for confirmation.")
|
|
2069
2083
|
_OUTPUT_OPT = typer.Option(
|
|
2070
|
-
None,
|
|
2084
|
+
None,
|
|
2085
|
+
"--json/--table",
|
|
2086
|
+
help="Force JSON or table output (default: table on a TTY, JSON piped).",
|
|
2071
2087
|
)
|
|
2072
2088
|
|
|
2073
2089
|
|
|
@@ -2082,7 +2098,7 @@ def _generated_call(
|
|
|
2082
2098
|
columns: list[str] | None = None,
|
|
2083
2099
|
confirm: str | None = None,
|
|
2084
2100
|
yes: bool = False,
|
|
2085
|
-
output:
|
|
2101
|
+
output: bool | None = None,
|
|
2086
2102
|
) -> None:
|
|
2087
2103
|
"""Shared runtime for generated commands: build the path, confirm if
|
|
2088
2104
|
needed, call the API, render the result."""
|
|
@@ -2239,7 +2255,7 @@ def gen_handles_create(
|
|
|
2239
2255
|
city: str | None = typer.Option(None),
|
|
2240
2256
|
region: str | None = typer.Option(None),
|
|
2241
2257
|
country: str | None = typer.Option(None),
|
|
2242
|
-
output:
|
|
2258
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2243
2259
|
) -> None:
|
|
2244
2260
|
"""Create a contact handle."""
|
|
2245
2261
|
|
|
@@ -2274,7 +2290,7 @@ def gen_handles_create(
|
|
|
2274
2290
|
def gen_handles_index(
|
|
2275
2291
|
ctx: typer.Context,
|
|
2276
2292
|
sort: str | None = _SORT_OPT,
|
|
2277
|
-
output:
|
|
2293
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2278
2294
|
) -> None:
|
|
2279
2295
|
"""List your contact handles."""
|
|
2280
2296
|
|
|
@@ -2292,7 +2308,7 @@ def gen_handles_index(
|
|
|
2292
2308
|
def gen_handles_show(
|
|
2293
2309
|
ctx: typer.Context,
|
|
2294
2310
|
handle_id: int = typer.Argument(..., metavar="HANDLE_ID"),
|
|
2295
|
-
output:
|
|
2311
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2296
2312
|
) -> None:
|
|
2297
2313
|
"""Show one contact handle."""
|
|
2298
2314
|
|
|
@@ -2309,7 +2325,7 @@ def gen_handles_show(
|
|
|
2309
2325
|
def gen_services_apps_index(
|
|
2310
2326
|
ctx: typer.Context,
|
|
2311
2327
|
sort: str | None = _SORT_OPT,
|
|
2312
|
-
output:
|
|
2328
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2313
2329
|
) -> None:
|
|
2314
2330
|
"""List apps."""
|
|
2315
2331
|
|
|
@@ -2327,7 +2343,7 @@ def gen_services_apps_index(
|
|
|
2327
2343
|
def gen_services_apps_show(
|
|
2328
2344
|
ctx: typer.Context,
|
|
2329
2345
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2330
|
-
output:
|
|
2346
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2331
2347
|
) -> None:
|
|
2332
2348
|
"""Show apps details."""
|
|
2333
2349
|
|
|
@@ -2346,7 +2362,7 @@ def gen_services_apps_state(
|
|
|
2346
2362
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2347
2363
|
state: str = typer.Argument(..., metavar="STATE"),
|
|
2348
2364
|
yes: bool = _YES_OPT,
|
|
2349
|
-
output:
|
|
2365
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2350
2366
|
) -> None:
|
|
2351
2367
|
"""Change the state of an app service."""
|
|
2352
2368
|
|
|
@@ -2365,7 +2381,7 @@ def gen_services_apps_state(
|
|
|
2365
2381
|
def gen_services_buckets_index(
|
|
2366
2382
|
ctx: typer.Context,
|
|
2367
2383
|
sort: str | None = _SORT_OPT,
|
|
2368
|
-
output:
|
|
2384
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2369
2385
|
) -> None:
|
|
2370
2386
|
"""List buckets."""
|
|
2371
2387
|
|
|
@@ -2383,7 +2399,7 @@ def gen_services_buckets_index(
|
|
|
2383
2399
|
def gen_services_buckets_show(
|
|
2384
2400
|
ctx: typer.Context,
|
|
2385
2401
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2386
|
-
output:
|
|
2402
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2387
2403
|
) -> None:
|
|
2388
2404
|
"""Show buckets details."""
|
|
2389
2405
|
|
|
@@ -2401,7 +2417,7 @@ def gen_services_containers_deploy(
|
|
|
2401
2417
|
ctx: typer.Context,
|
|
2402
2418
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2403
2419
|
yes: bool = _YES_OPT,
|
|
2404
|
-
output:
|
|
2420
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2405
2421
|
) -> None:
|
|
2406
2422
|
"""Deploy a container service."""
|
|
2407
2423
|
|
|
@@ -2420,7 +2436,7 @@ def gen_services_containers_deploy(
|
|
|
2420
2436
|
def gen_services_containers_index(
|
|
2421
2437
|
ctx: typer.Context,
|
|
2422
2438
|
sort: str | None = _SORT_OPT,
|
|
2423
|
-
output:
|
|
2439
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2424
2440
|
) -> None:
|
|
2425
2441
|
"""List containers."""
|
|
2426
2442
|
|
|
@@ -2440,7 +2456,7 @@ def gen_services_containers_instances_deploy(
|
|
|
2440
2456
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2441
2457
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2442
2458
|
yes: bool = _YES_OPT,
|
|
2443
|
-
output:
|
|
2459
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2444
2460
|
) -> None:
|
|
2445
2461
|
"""Deploy a container instance."""
|
|
2446
2462
|
|
|
@@ -2460,7 +2476,7 @@ def gen_services_containers_instances_index(
|
|
|
2460
2476
|
ctx: typer.Context,
|
|
2461
2477
|
service_id: str = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2462
2478
|
sort: str | None = _SORT_OPT,
|
|
2463
|
-
output:
|
|
2479
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2464
2480
|
) -> None:
|
|
2465
2481
|
"""List containers instances."""
|
|
2466
2482
|
|
|
@@ -2479,7 +2495,7 @@ def gen_services_containers_instances_logs(
|
|
|
2479
2495
|
ctx: typer.Context,
|
|
2480
2496
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2481
2497
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2482
|
-
output:
|
|
2498
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2483
2499
|
) -> None:
|
|
2484
2500
|
"""Show the logs of a container instance."""
|
|
2485
2501
|
|
|
@@ -2497,7 +2513,7 @@ def gen_services_containers_instances_show(
|
|
|
2497
2513
|
ctx: typer.Context,
|
|
2498
2514
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2499
2515
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2500
|
-
output:
|
|
2516
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2501
2517
|
) -> None:
|
|
2502
2518
|
"""Show containers instances details."""
|
|
2503
2519
|
|
|
@@ -2517,7 +2533,7 @@ def gen_services_containers_instances_state(
|
|
|
2517
2533
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2518
2534
|
state: str = typer.Argument(..., metavar="STATE"),
|
|
2519
2535
|
yes: bool = _YES_OPT,
|
|
2520
|
-
output:
|
|
2536
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2521
2537
|
) -> None:
|
|
2522
2538
|
"""Change the state of a container instance."""
|
|
2523
2539
|
|
|
@@ -2538,7 +2554,7 @@ def gen_services_containers_instances_update(
|
|
|
2538
2554
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2539
2555
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2540
2556
|
image: str | None = typer.Option(None),
|
|
2541
|
-
output:
|
|
2557
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2542
2558
|
) -> None:
|
|
2543
2559
|
"""Update containers instances."""
|
|
2544
2560
|
|
|
@@ -2558,7 +2574,7 @@ def gen_services_containers_instances_volumes_index(
|
|
|
2558
2574
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2559
2575
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2560
2576
|
sort: str | None = _SORT_OPT,
|
|
2561
|
-
output:
|
|
2577
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2562
2578
|
) -> None:
|
|
2563
2579
|
"""List containers instances volumes."""
|
|
2564
2580
|
|
|
@@ -2578,7 +2594,7 @@ def gen_services_containers_instances_volumes_show(
|
|
|
2578
2594
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2579
2595
|
instance_id: int = typer.Argument(..., metavar="INSTANCE_ID"),
|
|
2580
2596
|
volume_id: int = typer.Argument(..., metavar="VOLUME_ID"),
|
|
2581
|
-
output:
|
|
2597
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2582
2598
|
) -> None:
|
|
2583
2599
|
"""Show containers instances volumes details."""
|
|
2584
2600
|
|
|
@@ -2599,7 +2615,7 @@ def gen_services_containers_instances_volumes_update(
|
|
|
2599
2615
|
volume_id: int = typer.Argument(..., metavar="VOLUME_ID"),
|
|
2600
2616
|
path: str | None = typer.Option(None),
|
|
2601
2617
|
uid: str | None = typer.Option(None),
|
|
2602
|
-
output:
|
|
2618
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2603
2619
|
) -> None:
|
|
2604
2620
|
"""Update containers instances volumes."""
|
|
2605
2621
|
|
|
@@ -2617,7 +2633,7 @@ def gen_services_containers_instances_volumes_update(
|
|
|
2617
2633
|
def gen_services_containers_show(
|
|
2618
2634
|
ctx: typer.Context,
|
|
2619
2635
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2620
|
-
output:
|
|
2636
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2621
2637
|
) -> None:
|
|
2622
2638
|
"""Show containers details."""
|
|
2623
2639
|
|
|
@@ -2637,7 +2653,7 @@ def gen_services_containers_update(
|
|
|
2637
2653
|
registry_url: str | None = typer.Option(None),
|
|
2638
2654
|
description: str | None = typer.Option(None),
|
|
2639
2655
|
port: int | None = typer.Option(None),
|
|
2640
|
-
output:
|
|
2656
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2641
2657
|
) -> None:
|
|
2642
2658
|
"""Update containers."""
|
|
2643
2659
|
|
|
@@ -2655,7 +2671,7 @@ def gen_services_containers_update(
|
|
|
2655
2671
|
def gen_services_databases_clusters_index(
|
|
2656
2672
|
ctx: typer.Context,
|
|
2657
2673
|
sort: str | None = _SORT_OPT,
|
|
2658
|
-
output:
|
|
2674
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2659
2675
|
) -> None:
|
|
2660
2676
|
"""List databases clusters."""
|
|
2661
2677
|
|
|
@@ -2673,7 +2689,7 @@ def gen_services_databases_clusters_index(
|
|
|
2673
2689
|
def gen_services_databases_clusters_show(
|
|
2674
2690
|
ctx: typer.Context,
|
|
2675
2691
|
cluster_id: int = typer.Argument(..., metavar="CLUSTER_ID"),
|
|
2676
|
-
output:
|
|
2692
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2677
2693
|
) -> None:
|
|
2678
2694
|
"""Show databases clusters details."""
|
|
2679
2695
|
|
|
@@ -2691,7 +2707,7 @@ def gen_services_databases_clusters_users_index(
|
|
|
2691
2707
|
ctx: typer.Context,
|
|
2692
2708
|
cluster_id: int = typer.Argument(..., metavar="CLUSTER_ID"),
|
|
2693
2709
|
sort: str | None = _SORT_OPT,
|
|
2694
|
-
output:
|
|
2710
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2695
2711
|
) -> None:
|
|
2696
2712
|
"""List databases clusters users."""
|
|
2697
2713
|
|
|
@@ -2710,7 +2726,7 @@ def gen_services_databases_clusters_users_show(
|
|
|
2710
2726
|
ctx: typer.Context,
|
|
2711
2727
|
cluster_id: int = typer.Argument(..., metavar="CLUSTER_ID"),
|
|
2712
2728
|
user_id: int = typer.Argument(..., metavar="USER_ID"),
|
|
2713
|
-
output:
|
|
2729
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2714
2730
|
) -> None:
|
|
2715
2731
|
"""Show databases clusters users details."""
|
|
2716
2732
|
|
|
@@ -2727,7 +2743,7 @@ def gen_services_databases_clusters_users_show(
|
|
|
2727
2743
|
def gen_services_databases_index(
|
|
2728
2744
|
ctx: typer.Context,
|
|
2729
2745
|
sort: str | None = _SORT_OPT,
|
|
2730
|
-
output:
|
|
2746
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2731
2747
|
) -> None:
|
|
2732
2748
|
"""List databases."""
|
|
2733
2749
|
|
|
@@ -2747,7 +2763,7 @@ def gen_services_databases_permissions_create(
|
|
|
2747
2763
|
service_id: str = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2748
2764
|
user_id: str | None = typer.Option(None),
|
|
2749
2765
|
permissions: list[str] | None = typer.Option(None),
|
|
2750
|
-
output:
|
|
2766
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2751
2767
|
) -> None:
|
|
2752
2768
|
"""Create databases permissions."""
|
|
2753
2769
|
|
|
@@ -2765,7 +2781,7 @@ def gen_services_databases_permissions_create(
|
|
|
2765
2781
|
def gen_services_databases_show(
|
|
2766
2782
|
ctx: typer.Context,
|
|
2767
2783
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2768
|
-
output:
|
|
2784
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2769
2785
|
) -> None:
|
|
2770
2786
|
"""Show databases details."""
|
|
2771
2787
|
|
|
@@ -2784,7 +2800,7 @@ def gen_services_databases_store(
|
|
|
2784
2800
|
name: str | None = typer.Option(None),
|
|
2785
2801
|
client_id: int | None = typer.Option(None),
|
|
2786
2802
|
cluster_id: int | None = typer.Option(None),
|
|
2787
|
-
output:
|
|
2803
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2788
2804
|
) -> None:
|
|
2789
2805
|
"""Create databases."""
|
|
2790
2806
|
|
|
@@ -2805,7 +2821,7 @@ def gen_services_databases_users_store(
|
|
|
2805
2821
|
username: str | None = typer.Option(None),
|
|
2806
2822
|
password: str | None = typer.Option(None),
|
|
2807
2823
|
client_id: int | None = typer.Option(None),
|
|
2808
|
-
output:
|
|
2824
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2809
2825
|
) -> None:
|
|
2810
2826
|
"""Create databases users."""
|
|
2811
2827
|
|
|
@@ -2825,7 +2841,7 @@ def gen_services_databases_users_update(
|
|
|
2825
2841
|
cluster_id: str = typer.Argument(..., metavar="CLUSTER_ID"),
|
|
2826
2842
|
user_id: str = typer.Argument(..., metavar="USER_ID"),
|
|
2827
2843
|
password: str | None = typer.Option(None),
|
|
2828
|
-
output:
|
|
2844
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2829
2845
|
) -> None:
|
|
2830
2846
|
"""Update databases users."""
|
|
2831
2847
|
|
|
@@ -2850,7 +2866,7 @@ def gen_services_domains_create(
|
|
|
2850
2866
|
handle_id_owner: int | None = typer.Option(None),
|
|
2851
2867
|
handle_id_administrative: int | None = typer.Option(None),
|
|
2852
2868
|
handle_id_technical: int | None = typer.Option(None),
|
|
2853
|
-
output:
|
|
2869
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2854
2870
|
) -> None:
|
|
2855
2871
|
"""Create domains."""
|
|
2856
2872
|
|
|
@@ -2877,7 +2893,7 @@ def gen_services_domains_create(
|
|
|
2877
2893
|
def gen_services_domains_index(
|
|
2878
2894
|
ctx: typer.Context,
|
|
2879
2895
|
sort: str | None = _SORT_OPT,
|
|
2880
|
-
output:
|
|
2896
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2881
2897
|
) -> None:
|
|
2882
2898
|
"""List domains."""
|
|
2883
2899
|
|
|
@@ -2895,7 +2911,7 @@ def gen_services_domains_index(
|
|
|
2895
2911
|
def gen_services_domains_show(
|
|
2896
2912
|
ctx: typer.Context,
|
|
2897
2913
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2898
|
-
output:
|
|
2914
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2899
2915
|
) -> None:
|
|
2900
2916
|
"""Show domains details."""
|
|
2901
2917
|
|
|
@@ -2914,7 +2930,7 @@ def gen_services_emails_aliases_create(
|
|
|
2914
2930
|
service_id: str = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2915
2931
|
emailaddress: str | None = typer.Option(None),
|
|
2916
2932
|
alias: str | None = typer.Option(None),
|
|
2917
|
-
output:
|
|
2933
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2918
2934
|
) -> None:
|
|
2919
2935
|
"""Create emails aliases."""
|
|
2920
2936
|
|
|
@@ -2934,7 +2950,7 @@ def gen_services_emails_aliases_delete(
|
|
|
2934
2950
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2935
2951
|
alias_id: int = typer.Argument(..., metavar="ALIAS_ID"),
|
|
2936
2952
|
yes: bool = _YES_OPT,
|
|
2937
|
-
output:
|
|
2953
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2938
2954
|
) -> None:
|
|
2939
2955
|
"""Delete emails aliases."""
|
|
2940
2956
|
|
|
@@ -2954,7 +2970,7 @@ def gen_services_emails_aliases_index(
|
|
|
2954
2970
|
ctx: typer.Context,
|
|
2955
2971
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2956
2972
|
sort: str | None = _SORT_OPT,
|
|
2957
|
-
output:
|
|
2973
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2958
2974
|
) -> None:
|
|
2959
2975
|
"""List emails aliases."""
|
|
2960
2976
|
|
|
@@ -2973,7 +2989,7 @@ def gen_services_emails_aliases_show(
|
|
|
2973
2989
|
ctx: typer.Context,
|
|
2974
2990
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
2975
2991
|
alias_id: int = typer.Argument(..., metavar="ALIAS_ID"),
|
|
2976
|
-
output:
|
|
2992
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2977
2993
|
) -> None:
|
|
2978
2994
|
"""Show emails aliases details."""
|
|
2979
2995
|
|
|
@@ -2995,7 +3011,7 @@ def gen_services_emails_create(
|
|
|
2995
3011
|
return_path_domain: str | None = typer.Option(None),
|
|
2996
3012
|
relay_hosts: list[str] | None = typer.Option(None),
|
|
2997
3013
|
delivery_rate: int | None = typer.Option(None),
|
|
2998
|
-
output:
|
|
3014
|
+
output: bool | None = _OUTPUT_OPT,
|
|
2999
3015
|
) -> None:
|
|
3000
3016
|
"""Create emails."""
|
|
3001
3017
|
|
|
@@ -3021,7 +3037,7 @@ def gen_services_emails_delete(
|
|
|
3021
3037
|
ctx: typer.Context,
|
|
3022
3038
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3023
3039
|
yes: bool = _YES_OPT,
|
|
3024
|
-
output:
|
|
3040
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3025
3041
|
) -> None:
|
|
3026
3042
|
"""Delete emails."""
|
|
3027
3043
|
|
|
@@ -3040,7 +3056,7 @@ def gen_services_emails_delete(
|
|
|
3040
3056
|
def gen_services_emails_dkim_show(
|
|
3041
3057
|
ctx: typer.Context,
|
|
3042
3058
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3043
|
-
output:
|
|
3059
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3044
3060
|
) -> None:
|
|
3045
3061
|
"""Show the DKIM configuration of an email service."""
|
|
3046
3062
|
|
|
@@ -3059,7 +3075,7 @@ def gen_services_emails_forwardings_create(
|
|
|
3059
3075
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3060
3076
|
emailaddress: str | None = typer.Option(None),
|
|
3061
3077
|
target: str | None = typer.Option(None),
|
|
3062
|
-
output:
|
|
3078
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3063
3079
|
) -> None:
|
|
3064
3080
|
"""Create emails forwardings."""
|
|
3065
3081
|
|
|
@@ -3079,7 +3095,7 @@ def gen_services_emails_forwardings_delete(
|
|
|
3079
3095
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3080
3096
|
forwarding_id: int = typer.Argument(..., metavar="FORWARDING_ID"),
|
|
3081
3097
|
yes: bool = _YES_OPT,
|
|
3082
|
-
output:
|
|
3098
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3083
3099
|
) -> None:
|
|
3084
3100
|
"""Delete emails forwardings."""
|
|
3085
3101
|
|
|
@@ -3099,7 +3115,7 @@ def gen_services_emails_forwardings_index(
|
|
|
3099
3115
|
ctx: typer.Context,
|
|
3100
3116
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3101
3117
|
sort: str | None = _SORT_OPT,
|
|
3102
|
-
output:
|
|
3118
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3103
3119
|
) -> None:
|
|
3104
3120
|
"""List emails forwardings."""
|
|
3105
3121
|
|
|
@@ -3118,7 +3134,7 @@ def gen_services_emails_forwardings_show(
|
|
|
3118
3134
|
ctx: typer.Context,
|
|
3119
3135
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3120
3136
|
forwarding_id: int = typer.Argument(..., metavar="FORWARDING_ID"),
|
|
3121
|
-
output:
|
|
3137
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3122
3138
|
) -> None:
|
|
3123
3139
|
"""Show emails forwardings details."""
|
|
3124
3140
|
|
|
@@ -3135,7 +3151,7 @@ def gen_services_emails_forwardings_show(
|
|
|
3135
3151
|
def gen_services_emails_index(
|
|
3136
3152
|
ctx: typer.Context,
|
|
3137
3153
|
sort: str | None = _SORT_OPT,
|
|
3138
|
-
output:
|
|
3154
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3139
3155
|
) -> None:
|
|
3140
3156
|
"""List emails."""
|
|
3141
3157
|
|
|
@@ -3155,7 +3171,7 @@ def gen_services_emails_mailboxes_create(
|
|
|
3155
3171
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3156
3172
|
emailaddress: str | None = typer.Option(None),
|
|
3157
3173
|
password: str | None = typer.Option(None),
|
|
3158
|
-
output:
|
|
3174
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3159
3175
|
) -> None:
|
|
3160
3176
|
"""Create emails mailboxes."""
|
|
3161
3177
|
|
|
@@ -3175,7 +3191,7 @@ def gen_services_emails_mailboxes_delete(
|
|
|
3175
3191
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3176
3192
|
emailaddress: str = typer.Argument(..., metavar="EMAILADDRESS"),
|
|
3177
3193
|
yes: bool = _YES_OPT,
|
|
3178
|
-
output:
|
|
3194
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3179
3195
|
) -> None:
|
|
3180
3196
|
"""Delete emails mailboxes."""
|
|
3181
3197
|
|
|
@@ -3195,7 +3211,7 @@ def gen_services_emails_mailboxes_index(
|
|
|
3195
3211
|
ctx: typer.Context,
|
|
3196
3212
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3197
3213
|
sort: str | None = _SORT_OPT,
|
|
3198
|
-
output:
|
|
3214
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3199
3215
|
) -> None:
|
|
3200
3216
|
"""List emails mailboxes."""
|
|
3201
3217
|
|
|
@@ -3214,7 +3230,7 @@ def gen_services_emails_mailboxes_show(
|
|
|
3214
3230
|
ctx: typer.Context,
|
|
3215
3231
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3216
3232
|
emailaddress: str = typer.Argument(..., metavar="EMAILADDRESS"),
|
|
3217
|
-
output:
|
|
3233
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3218
3234
|
) -> None:
|
|
3219
3235
|
"""Show emails mailboxes details."""
|
|
3220
3236
|
|
|
@@ -3233,7 +3249,7 @@ def gen_services_emails_mailboxes_update(
|
|
|
3233
3249
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3234
3250
|
emailaddress: str = typer.Argument(..., metavar="EMAILADDRESS"),
|
|
3235
3251
|
password: str | None = typer.Option(None),
|
|
3236
|
-
output:
|
|
3252
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3237
3253
|
) -> None:
|
|
3238
3254
|
"""Update emails mailboxes."""
|
|
3239
3255
|
|
|
@@ -3252,7 +3268,7 @@ def gen_services_emails_records_index(
|
|
|
3252
3268
|
ctx: typer.Context,
|
|
3253
3269
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3254
3270
|
sort: str | None = _SORT_OPT,
|
|
3255
|
-
output:
|
|
3271
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3256
3272
|
) -> None:
|
|
3257
3273
|
"""List the DNS records an email service needs."""
|
|
3258
3274
|
|
|
@@ -3270,7 +3286,7 @@ def gen_services_emails_records_index(
|
|
|
3270
3286
|
def gen_services_emails_show(
|
|
3271
3287
|
ctx: typer.Context,
|
|
3272
3288
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3273
|
-
output:
|
|
3289
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3274
3290
|
) -> None:
|
|
3275
3291
|
"""Show emails details."""
|
|
3276
3292
|
|
|
@@ -3288,7 +3304,7 @@ def gen_services_emails_transactional_aliases_create(
|
|
|
3288
3304
|
ctx: typer.Context,
|
|
3289
3305
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3290
3306
|
domain: str | None = typer.Option(None),
|
|
3291
|
-
output:
|
|
3307
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3292
3308
|
) -> None:
|
|
3293
3309
|
"""Create emails transactional aliases."""
|
|
3294
3310
|
|
|
@@ -3308,7 +3324,7 @@ def gen_services_emails_transactional_aliases_delete(
|
|
|
3308
3324
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3309
3325
|
alias_id: int = typer.Argument(..., metavar="ALIAS_ID"),
|
|
3310
3326
|
yes: bool = _YES_OPT,
|
|
3311
|
-
output:
|
|
3327
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3312
3328
|
) -> None:
|
|
3313
3329
|
"""Delete emails transactional aliases."""
|
|
3314
3330
|
|
|
@@ -3328,7 +3344,7 @@ def gen_services_emails_transactional_aliases_index(
|
|
|
3328
3344
|
ctx: typer.Context,
|
|
3329
3345
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3330
3346
|
sort: str | None = _SORT_OPT,
|
|
3331
|
-
output:
|
|
3347
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3332
3348
|
) -> None:
|
|
3333
3349
|
"""List emails transactional aliases."""
|
|
3334
3350
|
|
|
@@ -3349,7 +3365,7 @@ def gen_services_emails_transactional_keys_create(
|
|
|
3349
3365
|
name: str | None = typer.Option(None),
|
|
3350
3366
|
key: str | None = typer.Option(None),
|
|
3351
3367
|
active: bool | None = typer.Option(None),
|
|
3352
|
-
output:
|
|
3368
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3353
3369
|
) -> None:
|
|
3354
3370
|
"""Create emails transactional keys."""
|
|
3355
3371
|
|
|
@@ -3369,7 +3385,7 @@ def gen_services_emails_transactional_keys_delete(
|
|
|
3369
3385
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3370
3386
|
key_id: int = typer.Argument(..., metavar="KEY_ID"),
|
|
3371
3387
|
yes: bool = _YES_OPT,
|
|
3372
|
-
output:
|
|
3388
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3373
3389
|
) -> None:
|
|
3374
3390
|
"""Delete emails transactional keys."""
|
|
3375
3391
|
|
|
@@ -3389,7 +3405,7 @@ def gen_services_emails_transactional_keys_index(
|
|
|
3389
3405
|
ctx: typer.Context,
|
|
3390
3406
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3391
3407
|
sort: str | None = _SORT_OPT,
|
|
3392
|
-
output:
|
|
3408
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3393
3409
|
) -> None:
|
|
3394
3410
|
"""List emails transactional keys."""
|
|
3395
3411
|
|
|
@@ -3408,7 +3424,7 @@ def gen_services_emails_transactional_keys_show(
|
|
|
3408
3424
|
ctx: typer.Context,
|
|
3409
3425
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3410
3426
|
key_id: int = typer.Argument(..., metavar="KEY_ID"),
|
|
3411
|
-
output:
|
|
3427
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3412
3428
|
) -> None:
|
|
3413
3429
|
"""Show emails transactional keys details."""
|
|
3414
3430
|
|
|
@@ -3429,7 +3445,7 @@ def gen_services_emails_transactional_keys_update(
|
|
|
3429
3445
|
name: str | None = typer.Option(None),
|
|
3430
3446
|
key: str | None = typer.Option(None),
|
|
3431
3447
|
active: bool | None = typer.Option(None),
|
|
3432
|
-
output:
|
|
3448
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3433
3449
|
) -> None:
|
|
3434
3450
|
"""Update emails transactional keys."""
|
|
3435
3451
|
|
|
@@ -3450,7 +3466,7 @@ def gen_services_emails_transactional_users_create(
|
|
|
3450
3466
|
emailaddress: str | None = typer.Option(None),
|
|
3451
3467
|
password: str | None = typer.Option(None),
|
|
3452
3468
|
delivery_mode: str | None = typer.Option(None),
|
|
3453
|
-
output:
|
|
3469
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3454
3470
|
) -> None:
|
|
3455
3471
|
"""Create emails transactional users."""
|
|
3456
3472
|
|
|
@@ -3474,7 +3490,7 @@ def gen_services_emails_transactional_users_delete(
|
|
|
3474
3490
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3475
3491
|
user_id: int = typer.Argument(..., metavar="USER_ID"),
|
|
3476
3492
|
yes: bool = _YES_OPT,
|
|
3477
|
-
output:
|
|
3493
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3478
3494
|
) -> None:
|
|
3479
3495
|
"""Delete emails transactional users."""
|
|
3480
3496
|
|
|
@@ -3494,7 +3510,7 @@ def gen_services_emails_transactional_users_index(
|
|
|
3494
3510
|
ctx: typer.Context,
|
|
3495
3511
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3496
3512
|
sort: str | None = _SORT_OPT,
|
|
3497
|
-
output:
|
|
3513
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3498
3514
|
) -> None:
|
|
3499
3515
|
"""List emails transactional users."""
|
|
3500
3516
|
|
|
@@ -3513,7 +3529,7 @@ def gen_services_emails_transactional_users_show(
|
|
|
3513
3529
|
ctx: typer.Context,
|
|
3514
3530
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3515
3531
|
user_id: int = typer.Argument(..., metavar="USER_ID"),
|
|
3516
|
-
output:
|
|
3532
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3517
3533
|
) -> None:
|
|
3518
3534
|
"""Show emails transactional users details."""
|
|
3519
3535
|
|
|
@@ -3533,7 +3549,7 @@ def gen_services_emails_transactional_users_update(
|
|
|
3533
3549
|
user_id: int = typer.Argument(..., metavar="USER_ID"),
|
|
3534
3550
|
password: str | None = typer.Option(None),
|
|
3535
3551
|
delivery_mode: str | None = typer.Option(None),
|
|
3536
|
-
output:
|
|
3552
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3537
3553
|
) -> None:
|
|
3538
3554
|
"""Update emails transactional users."""
|
|
3539
3555
|
|
|
@@ -3551,7 +3567,7 @@ def gen_services_emails_transactional_users_update(
|
|
|
3551
3567
|
def gen_services_forwards_index(
|
|
3552
3568
|
ctx: typer.Context,
|
|
3553
3569
|
sort: str | None = _SORT_OPT,
|
|
3554
|
-
output:
|
|
3570
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3555
3571
|
) -> None:
|
|
3556
3572
|
"""List forwards."""
|
|
3557
3573
|
|
|
@@ -3569,7 +3585,7 @@ def gen_services_forwards_index(
|
|
|
3569
3585
|
def gen_services_forwards_show(
|
|
3570
3586
|
ctx: typer.Context,
|
|
3571
3587
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3572
|
-
output:
|
|
3588
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3573
3589
|
) -> None:
|
|
3574
3590
|
"""Show forwards details."""
|
|
3575
3591
|
|
|
@@ -3587,7 +3603,7 @@ def gen_services_proxies_down(
|
|
|
3587
3603
|
ctx: typer.Context,
|
|
3588
3604
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3589
3605
|
yes: bool = _YES_OPT,
|
|
3590
|
-
output:
|
|
3606
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3591
3607
|
) -> None:
|
|
3592
3608
|
"""Bring a proxy down."""
|
|
3593
3609
|
|
|
@@ -3606,7 +3622,7 @@ def gen_services_proxies_down(
|
|
|
3606
3622
|
def gen_services_proxies_index(
|
|
3607
3623
|
ctx: typer.Context,
|
|
3608
3624
|
sort: str | None = _SORT_OPT,
|
|
3609
|
-
output:
|
|
3625
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3610
3626
|
) -> None:
|
|
3611
3627
|
"""List proxies."""
|
|
3612
3628
|
|
|
@@ -3624,7 +3640,7 @@ def gen_services_proxies_index(
|
|
|
3624
3640
|
def gen_services_proxies_show(
|
|
3625
3641
|
ctx: typer.Context,
|
|
3626
3642
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3627
|
-
output:
|
|
3643
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3628
3644
|
) -> None:
|
|
3629
3645
|
"""Show proxies details."""
|
|
3630
3646
|
|
|
@@ -3642,7 +3658,7 @@ def gen_services_proxies_up(
|
|
|
3642
3658
|
ctx: typer.Context,
|
|
3643
3659
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3644
3660
|
yes: bool = _YES_OPT,
|
|
3645
|
-
output:
|
|
3661
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3646
3662
|
) -> None:
|
|
3647
3663
|
"""Bring a proxy up."""
|
|
3648
3664
|
|
|
@@ -3661,7 +3677,7 @@ def gen_services_proxies_up(
|
|
|
3661
3677
|
def gen_services_searches_index(
|
|
3662
3678
|
ctx: typer.Context,
|
|
3663
3679
|
sort: str | None = _SORT_OPT,
|
|
3664
|
-
output:
|
|
3680
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3665
3681
|
) -> None:
|
|
3666
3682
|
"""List searches."""
|
|
3667
3683
|
|
|
@@ -3679,7 +3695,7 @@ def gen_services_searches_index(
|
|
|
3679
3695
|
def gen_services_searches_show(
|
|
3680
3696
|
ctx: typer.Context,
|
|
3681
3697
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3682
|
-
output:
|
|
3698
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3683
3699
|
) -> None:
|
|
3684
3700
|
"""Show searches details."""
|
|
3685
3701
|
|
|
@@ -3696,7 +3712,7 @@ def gen_services_searches_show(
|
|
|
3696
3712
|
def gen_services_servers_index(
|
|
3697
3713
|
ctx: typer.Context,
|
|
3698
3714
|
sort: str | None = _SORT_OPT,
|
|
3699
|
-
output:
|
|
3715
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3700
3716
|
) -> None:
|
|
3701
3717
|
"""List servers."""
|
|
3702
3718
|
|
|
@@ -3714,7 +3730,7 @@ def gen_services_servers_index(
|
|
|
3714
3730
|
def gen_services_servers_show(
|
|
3715
3731
|
ctx: typer.Context,
|
|
3716
3732
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3717
|
-
output:
|
|
3733
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3718
3734
|
) -> None:
|
|
3719
3735
|
"""Show servers details."""
|
|
3720
3736
|
|
|
@@ -3733,7 +3749,7 @@ def gen_services_servers_state(
|
|
|
3733
3749
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3734
3750
|
state: str = typer.Argument(..., metavar="STATE"),
|
|
3735
3751
|
yes: bool = _YES_OPT,
|
|
3736
|
-
output:
|
|
3752
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3737
3753
|
) -> None:
|
|
3738
3754
|
"""Change the state of a server."""
|
|
3739
3755
|
|
|
@@ -3752,7 +3768,7 @@ def gen_services_servers_state(
|
|
|
3752
3768
|
def gen_services_sites_index(
|
|
3753
3769
|
ctx: typer.Context,
|
|
3754
3770
|
sort: str | None = _SORT_OPT,
|
|
3755
|
-
output:
|
|
3771
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3756
3772
|
) -> None:
|
|
3757
3773
|
"""List sites."""
|
|
3758
3774
|
|
|
@@ -3770,7 +3786,7 @@ def gen_services_sites_index(
|
|
|
3770
3786
|
def gen_services_sites_show(
|
|
3771
3787
|
ctx: typer.Context,
|
|
3772
3788
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3773
|
-
output:
|
|
3789
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3774
3790
|
) -> None:
|
|
3775
3791
|
"""Show sites details."""
|
|
3776
3792
|
|
|
@@ -3787,7 +3803,7 @@ def gen_services_sites_show(
|
|
|
3787
3803
|
def gen_services_spams_clusters_index(
|
|
3788
3804
|
ctx: typer.Context,
|
|
3789
3805
|
sort: str | None = _SORT_OPT,
|
|
3790
|
-
output:
|
|
3806
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3791
3807
|
) -> None:
|
|
3792
3808
|
"""List spams clusters."""
|
|
3793
3809
|
|
|
@@ -3805,7 +3821,7 @@ def gen_services_spams_clusters_index(
|
|
|
3805
3821
|
def gen_services_spams_clusters_show(
|
|
3806
3822
|
ctx: typer.Context,
|
|
3807
3823
|
cluster_id: int = typer.Argument(..., metavar="CLUSTER_ID"),
|
|
3808
|
-
output:
|
|
3824
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3809
3825
|
) -> None:
|
|
3810
3826
|
"""Show spams clusters details."""
|
|
3811
3827
|
|
|
@@ -3823,7 +3839,7 @@ def gen_services_spams_domain_create(
|
|
|
3823
3839
|
ctx: typer.Context,
|
|
3824
3840
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3825
3841
|
domain: str | None = typer.Option(None),
|
|
3826
|
-
output:
|
|
3842
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3827
3843
|
) -> None:
|
|
3828
3844
|
"""Create spams domain."""
|
|
3829
3845
|
|
|
@@ -3843,7 +3859,7 @@ def gen_services_spams_domain_delete(
|
|
|
3843
3859
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3844
3860
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
3845
3861
|
yes: bool = _YES_OPT,
|
|
3846
|
-
output:
|
|
3862
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3847
3863
|
) -> None:
|
|
3848
3864
|
"""Delete spams domain."""
|
|
3849
3865
|
|
|
@@ -3864,7 +3880,7 @@ def gen_services_spams_domain_dkim_disable(
|
|
|
3864
3880
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3865
3881
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
3866
3882
|
yes: bool = _YES_OPT,
|
|
3867
|
-
output:
|
|
3883
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3868
3884
|
) -> None:
|
|
3869
3885
|
"""Disable DKIM for a spam filter domain."""
|
|
3870
3886
|
|
|
@@ -3885,7 +3901,7 @@ def gen_services_spams_domain_dkim_enable(
|
|
|
3885
3901
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3886
3902
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
3887
3903
|
yes: bool = _YES_OPT,
|
|
3888
|
-
output:
|
|
3904
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3889
3905
|
) -> None:
|
|
3890
3906
|
"""Enable DKIM for a spam filter domain."""
|
|
3891
3907
|
|
|
@@ -3905,7 +3921,7 @@ def gen_services_spams_domain_index(
|
|
|
3905
3921
|
ctx: typer.Context,
|
|
3906
3922
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3907
3923
|
sort: str | None = _SORT_OPT,
|
|
3908
|
-
output:
|
|
3924
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3909
3925
|
) -> None:
|
|
3910
3926
|
"""List spams domain."""
|
|
3911
3927
|
|
|
@@ -3924,7 +3940,7 @@ def gen_services_spams_domain_show(
|
|
|
3924
3940
|
ctx: typer.Context,
|
|
3925
3941
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3926
3942
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
3927
|
-
output:
|
|
3943
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3928
3944
|
) -> None:
|
|
3929
3945
|
"""Show spams domain details."""
|
|
3930
3946
|
|
|
@@ -3941,7 +3957,7 @@ def gen_services_spams_domain_show(
|
|
|
3941
3957
|
def gen_services_spams_index(
|
|
3942
3958
|
ctx: typer.Context,
|
|
3943
3959
|
sort: str | None = _SORT_OPT,
|
|
3944
|
-
output:
|
|
3960
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3945
3961
|
) -> None:
|
|
3946
3962
|
"""List spams."""
|
|
3947
3963
|
|
|
@@ -3959,7 +3975,7 @@ def gen_services_spams_index(
|
|
|
3959
3975
|
def gen_services_spams_show(
|
|
3960
3976
|
ctx: typer.Context,
|
|
3961
3977
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
3962
|
-
output:
|
|
3978
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3963
3979
|
) -> None:
|
|
3964
3980
|
"""Show spams details."""
|
|
3965
3981
|
|
|
@@ -3979,7 +3995,7 @@ def gen_services_spams_transports_create(
|
|
|
3979
3995
|
domain: str | None = typer.Option(None),
|
|
3980
3996
|
host: str | None = typer.Option(None),
|
|
3981
3997
|
port: int | None = typer.Option(None),
|
|
3982
|
-
output:
|
|
3998
|
+
output: bool | None = _OUTPUT_OPT,
|
|
3983
3999
|
) -> None:
|
|
3984
4000
|
"""Create spams transports."""
|
|
3985
4001
|
|
|
@@ -3999,7 +4015,7 @@ def gen_services_spams_transports_delete(
|
|
|
3999
4015
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
4000
4016
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
4001
4017
|
yes: bool = _YES_OPT,
|
|
4002
|
-
output:
|
|
4018
|
+
output: bool | None = _OUTPUT_OPT,
|
|
4003
4019
|
) -> None:
|
|
4004
4020
|
"""Delete spams transports."""
|
|
4005
4021
|
|
|
@@ -4019,7 +4035,7 @@ def gen_services_spams_transports_index(
|
|
|
4019
4035
|
ctx: typer.Context,
|
|
4020
4036
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
4021
4037
|
sort: str | None = _SORT_OPT,
|
|
4022
|
-
output:
|
|
4038
|
+
output: bool | None = _OUTPUT_OPT,
|
|
4023
4039
|
) -> None:
|
|
4024
4040
|
"""List spams transports."""
|
|
4025
4041
|
|
|
@@ -4038,7 +4054,7 @@ def gen_services_spams_transports_show(
|
|
|
4038
4054
|
ctx: typer.Context,
|
|
4039
4055
|
service_id: int = typer.Argument(..., metavar="SERVICE_ID"),
|
|
4040
4056
|
domain: str = typer.Argument(..., metavar="DOMAIN"),
|
|
4041
|
-
output:
|
|
4057
|
+
output: bool | None = _OUTPUT_OPT,
|
|
4042
4058
|
) -> None:
|
|
4043
4059
|
"""Show spams transports details."""
|
|
4044
4060
|
|
|
@@ -386,7 +386,7 @@ def test_cert_list_shows_issued(configured, isolated_config):
|
|
|
386
386
|
import json
|
|
387
387
|
|
|
388
388
|
_write_cert(dncli.config_dir() / "certs" / "example.com", days=45)
|
|
389
|
-
result = runner.invoke(app, ["cert", "list", "
|
|
389
|
+
result = runner.invoke(app, ["cert", "list", "--json"])
|
|
390
390
|
assert result.exit_code == 0, result.output
|
|
391
391
|
rows = json.loads(result.output)
|
|
392
392
|
assert rows[0]["domain"] == "example.com"
|
|
@@ -45,7 +45,7 @@ def test_services_list_emits_json_and_bearer_header(configured):
|
|
|
45
45
|
}
|
|
46
46
|
]
|
|
47
47
|
route = respx.get(f"{API}/services").mock(return_value=Response(200, json=services))
|
|
48
|
-
result = runner.invoke(app, ["--
|
|
48
|
+
result = runner.invoke(app, ["--json", "services", "list"])
|
|
49
49
|
assert result.exit_code == 0
|
|
50
50
|
assert json.loads(result.output) == services
|
|
51
51
|
request = route.calls.last.request
|
|
@@ -57,11 +57,9 @@ def test_services_list_emits_json_and_bearer_header(configured):
|
|
|
57
57
|
def test_trailing_output_option_beats_global(configured):
|
|
58
58
|
services = [{"service_id": 1}]
|
|
59
59
|
respx.get(f"{API}/services").mock(return_value=Response(200, json=services))
|
|
60
|
-
# per-command --
|
|
61
|
-
# global
|
|
62
|
-
result = runner.invoke(
|
|
63
|
-
app, ["--output", "table", "services", "list", "--output", "json"]
|
|
64
|
-
)
|
|
60
|
+
# per-command --json works after the subcommand and wins over the
|
|
61
|
+
# global --table
|
|
62
|
+
result = runner.invoke(app, ["--table", "services", "list", "--json"])
|
|
65
63
|
assert result.exit_code == 0
|
|
66
64
|
assert json.loads(result.stdout) == services
|
|
67
65
|
|
|
@@ -72,7 +70,7 @@ def test_services_list_unwraps_laravel_envelope(configured):
|
|
|
72
70
|
respx.get(f"{API}/services").mock(
|
|
73
71
|
return_value=Response(200, json={"data": services})
|
|
74
72
|
)
|
|
75
|
-
result = runner.invoke(app, ["--
|
|
73
|
+
result = runner.invoke(app, ["--json", "services", "list"])
|
|
76
74
|
assert result.exit_code == 0
|
|
77
75
|
assert json.loads(result.output) == services
|
|
78
76
|
|
|
@@ -84,9 +82,7 @@ def test_services_list_sort_option(configured):
|
|
|
84
82
|
{"service_id": 1, "entity": "geleijn.net"},
|
|
85
83
|
]
|
|
86
84
|
respx.get(f"{API}/services").mock(return_value=Response(200, json=services))
|
|
87
|
-
result = runner.invoke(
|
|
88
|
-
app, ["--output", "json", "services", "list", "--sort", "entity"]
|
|
89
|
-
)
|
|
85
|
+
result = runner.invoke(app, ["--json", "services", "list", "--sort", "entity"])
|
|
90
86
|
assert result.exit_code == 0
|
|
91
87
|
assert [s["entity"] for s in json.loads(result.output)] == [
|
|
92
88
|
"geleijn.net",
|
|
@@ -116,7 +112,7 @@ def test_records_list_sort_descending(configured):
|
|
|
116
112
|
)
|
|
117
113
|
result = runner.invoke(
|
|
118
114
|
app,
|
|
119
|
-
["--
|
|
115
|
+
["--json", "dns", "records", "list", "example.com", "--sort", "-ttl"],
|
|
120
116
|
)
|
|
121
117
|
assert result.exit_code == 0
|
|
122
118
|
assert [r["ttl"] for r in json.loads(result.output)] == [3600, 60]
|
|
@@ -137,7 +133,7 @@ def test_services_show(configured):
|
|
|
137
133
|
respx.get(f"{API}/services/42").mock(
|
|
138
134
|
return_value=Response(200, json={"service_id": 42, "type": "email"})
|
|
139
135
|
)
|
|
140
|
-
result = runner.invoke(app, ["--
|
|
136
|
+
result = runner.invoke(app, ["--json", "services", "show", "42"])
|
|
141
137
|
assert result.exit_code == 0
|
|
142
138
|
assert json.loads(result.output)["service_id"] == 42
|
|
143
139
|
|
|
@@ -146,7 +142,7 @@ def test_services_show(configured):
|
|
|
146
142
|
def test_zones_list(configured):
|
|
147
143
|
zones = [{"id": "example.com.", "name": "example.com.", "kind": "Master"}]
|
|
148
144
|
respx.get(f"{API}/services/dns/zones").mock(return_value=Response(200, json=zones))
|
|
149
|
-
result = runner.invoke(app, ["--
|
|
145
|
+
result = runner.invoke(app, ["--json", "dns", "zones", "list"])
|
|
150
146
|
assert result.exit_code == 0
|
|
151
147
|
assert json.loads(result.output) == zones
|
|
152
148
|
|
|
@@ -172,9 +168,7 @@ def test_zones_show_table_mode(configured):
|
|
|
172
168
|
respx.get(f"{API}/services/dns/zones/example.com.").mock(
|
|
173
169
|
return_value=Response(200, json=ZONE)
|
|
174
170
|
)
|
|
175
|
-
result = runner.invoke(
|
|
176
|
-
app, ["--output", "table", "dns", "zones", "show", "example.com"]
|
|
177
|
-
)
|
|
171
|
+
result = runner.invoke(app, ["--table", "dns", "zones", "show", "example.com"])
|
|
178
172
|
assert result.exit_code == 0
|
|
179
173
|
assert "www.example.com." in result.output
|
|
180
174
|
assert "192.0.2.1" in result.output
|
|
@@ -187,9 +181,7 @@ def test_zones_show_accepts_trailing_dot_form_too(configured):
|
|
|
187
181
|
)
|
|
188
182
|
# both spellings resolve to the canonical PowerDNS zone id
|
|
189
183
|
for zone_arg in ("example.com", "example.com."):
|
|
190
|
-
result = runner.invoke(
|
|
191
|
-
app, ["--output", "json", "dns", "zones", "show", zone_arg]
|
|
192
|
-
)
|
|
184
|
+
result = runner.invoke(app, ["--json", "dns", "zones", "show", zone_arg])
|
|
193
185
|
assert result.exit_code == 0, result.output
|
|
194
186
|
assert route.call_count == 2
|
|
195
187
|
|
|
@@ -199,9 +191,7 @@ def test_records_list_flattens_rrsets(configured):
|
|
|
199
191
|
respx.get(f"{API}/services/dns/zones/example.com.").mock(
|
|
200
192
|
return_value=Response(200, json=ZONE)
|
|
201
193
|
)
|
|
202
|
-
result = runner.invoke(
|
|
203
|
-
app, ["--output", "json", "dns", "records", "list", "example.com"]
|
|
204
|
-
)
|
|
194
|
+
result = runner.invoke(app, ["--json", "dns", "records", "list", "example.com"])
|
|
205
195
|
assert result.exit_code == 0
|
|
206
196
|
rows = json.loads(result.output)
|
|
207
197
|
assert rows == [
|
|
@@ -318,7 +308,7 @@ def test_retry_on_429_honors_retry_after(configured, monkeypatch):
|
|
|
318
308
|
Response(429, headers={"Retry-After": "3"}),
|
|
319
309
|
Response(200, json=[]),
|
|
320
310
|
]
|
|
321
|
-
result = runner.invoke(app, ["--
|
|
311
|
+
result = runner.invoke(app, ["--json", "services", "list"])
|
|
322
312
|
assert result.exit_code == 0
|
|
323
313
|
assert route.call_count == 2
|
|
324
314
|
assert sleeps == [3.0]
|
|
@@ -397,7 +387,7 @@ def test_configure_unknown_provider(isolated_config):
|
|
|
397
387
|
def test_configure_list_masks_secrets(write_profile):
|
|
398
388
|
write_profile(api_key="dn_abcdefghijklmnop")
|
|
399
389
|
write_profile("transip:personal", login="loek", private_key_file="/x.pem")
|
|
400
|
-
result = runner.invoke(app, ["--
|
|
390
|
+
result = runner.invoke(app, ["--json", "configure", "list"])
|
|
401
391
|
assert result.exit_code == 0
|
|
402
392
|
rows = {row["profile"]: row for row in json.loads(result.output)}
|
|
403
393
|
assert rows["default"]["type"] == "devnomads"
|
|
@@ -22,7 +22,7 @@ def configured(write_profile):
|
|
|
22
22
|
def test_handles_list(configured):
|
|
23
23
|
handles = [{"handle_id": 7, "firstname": "Loek"}]
|
|
24
24
|
respx.get(f"{API}/handles").mock(return_value=Response(200, json={"data": handles}))
|
|
25
|
-
result = runner.invoke(app, ["--
|
|
25
|
+
result = runner.invoke(app, ["--json", "handles", "list"])
|
|
26
26
|
assert result.exit_code == 0
|
|
27
27
|
assert json.loads(result.output) == handles
|
|
28
28
|
|
|
@@ -35,8 +35,7 @@ def test_nested_path_params(configured):
|
|
|
35
35
|
result = runner.invoke(
|
|
36
36
|
app,
|
|
37
37
|
[
|
|
38
|
-
"--
|
|
39
|
-
"json",
|
|
38
|
+
"--json",
|
|
40
39
|
"containers",
|
|
41
40
|
"instances",
|
|
42
41
|
"volumes",
|
|
@@ -138,7 +137,7 @@ def test_table_mode_flattens_nested_detail_objects(configured):
|
|
|
138
137
|
)
|
|
139
138
|
result = runner.invoke(
|
|
140
139
|
app,
|
|
141
|
-
["--
|
|
140
|
+
["--table", "proxies", "list"],
|
|
142
141
|
env={"COLUMNS": "200"}, # wide terminal so rich does not truncate
|
|
143
142
|
)
|
|
144
143
|
assert result.exit_code == 0
|
|
@@ -153,7 +152,7 @@ def test_json_mode_keeps_raw_nested_shape(configured):
|
|
|
153
152
|
respx.get(f"{API}/services/proxies").mock(
|
|
154
153
|
return_value=Response(200, json={"data": PROXIES})
|
|
155
154
|
)
|
|
156
|
-
result = runner.invoke(app, ["--
|
|
155
|
+
result = runner.invoke(app, ["--json", "proxies", "list"])
|
|
157
156
|
assert result.exit_code == 0
|
|
158
157
|
assert json.loads(result.output) == PROXIES
|
|
159
158
|
|
|
@@ -163,7 +162,7 @@ def test_trailing_output_option_on_generated_command(configured):
|
|
|
163
162
|
respx.get(f"{API}/services/forwards/2493").mock(
|
|
164
163
|
return_value=Response(200, json={"data": {"service_id": 2493}})
|
|
165
164
|
)
|
|
166
|
-
result = runner.invoke(app, ["forwards", "show", "2493", "--
|
|
165
|
+
result = runner.invoke(app, ["forwards", "show", "2493", "--json"])
|
|
167
166
|
assert result.exit_code == 0, result.output
|
|
168
167
|
assert json.loads(result.stdout)["service_id"] == 2493
|
|
169
168
|
|
|
@@ -172,7 +171,7 @@ def test_trailing_output_option_on_generated_command(configured):
|
|
|
172
171
|
def test_unique_command_prefixes_resolve(configured):
|
|
173
172
|
respx.get(f"{API}/services/emails").mock(return_value=Response(200, json=[]))
|
|
174
173
|
# `dncli e l` -> `dncli emails list`
|
|
175
|
-
result = runner.invoke(app, ["e", "l", "--
|
|
174
|
+
result = runner.invoke(app, ["e", "l", "--json"])
|
|
176
175
|
assert result.exit_code == 0, result.output
|
|
177
176
|
assert json.loads(result.stdout) == []
|
|
178
177
|
|
|
@@ -196,7 +195,7 @@ def test_exact_command_name_always_wins(configured):
|
|
|
196
195
|
@respx.mock
|
|
197
196
|
def test_plain_get_does_not_confirm(configured):
|
|
198
197
|
respx.get(f"{API}/services/servers").mock(return_value=Response(200, json=[]))
|
|
199
|
-
result = runner.invoke(app, ["--
|
|
198
|
+
result = runner.invoke(app, ["--json", "servers", "list"])
|
|
200
199
|
assert result.exit_code == 0
|
|
201
200
|
|
|
202
201
|
|
|
@@ -206,7 +205,7 @@ def test_generated_list_supports_sort(configured):
|
|
|
206
205
|
respx.get(f"{API}/services/servers").mock(return_value=Response(200, json=servers))
|
|
207
206
|
result = runner.invoke(
|
|
208
207
|
app,
|
|
209
|
-
["--
|
|
208
|
+
["--json", "servers", "list", "--sort", "service_id"],
|
|
210
209
|
)
|
|
211
210
|
assert result.exit_code == 0
|
|
212
211
|
assert [s["service_id"] for s in json.loads(result.output)] == [1, 2]
|
|
@@ -231,25 +231,25 @@ def test_cell_detail_keeps_per_item_lines():
|
|
|
231
231
|
assert _cell(insts) == "id=7 state_last_known=running"
|
|
232
232
|
|
|
233
233
|
|
|
234
|
-
def
|
|
234
|
+
def test_auto_columns_drops_empty_and_object_lists_only():
|
|
235
235
|
rows = [
|
|
236
236
|
{"id": 1, "port": 80, "registry": "same", "blank": "", "instances": [{"i": 7}]},
|
|
237
237
|
{"id": 2, "port": 81, "registry": "same", "blank": "", "instances": [{"i": 8}]},
|
|
238
238
|
]
|
|
239
|
-
#
|
|
240
|
-
#
|
|
241
|
-
assert _auto_columns(rows) == ["id", "port"]
|
|
239
|
+
# blank is empty and instances is an object list -> dropped; every other
|
|
240
|
+
# scalar is kept, including the constant `registry`.
|
|
241
|
+
assert _auto_columns(rows) == ["id", "port", "registry"]
|
|
242
242
|
|
|
243
243
|
|
|
244
|
-
def
|
|
244
|
+
def test_auto_columns_keeps_constant_scalar_columns():
|
|
245
245
|
rows = [{"id": 1, "x": 9, "y": "a"}, {"id": 1, "x": 9, "y": "b"}]
|
|
246
|
-
#
|
|
247
|
-
assert _auto_columns(rows) == ["id", "y"]
|
|
246
|
+
# constant columns are no longer dropped - normal fields always show
|
|
247
|
+
assert _auto_columns(rows) == ["id", "x", "y"]
|
|
248
248
|
|
|
249
249
|
|
|
250
250
|
def test_auto_columns_single_row_keeps_nonempty_scalars():
|
|
251
251
|
rows = [{"id": 1, "name": "x", "blank": None, "items": [{"a": 1}]}]
|
|
252
|
-
#
|
|
252
|
+
# empty and object-list columns go, scalars stay
|
|
253
253
|
assert _auto_columns(rows) == ["id", "name"]
|
|
254
254
|
|
|
255
255
|
|
|
@@ -266,8 +266,8 @@ def test_object_table_uses_auto_columns():
|
|
|
266
266
|
{"emailaddress": "b@x", "quota": 2, "domain": "x"},
|
|
267
267
|
]
|
|
268
268
|
table = _object_table(items)
|
|
269
|
-
#
|
|
270
|
-
assert [c.header for c in table.columns] == ["emailaddress", "quota"]
|
|
269
|
+
# all scalar sub-fields are kept (empties/object-lists would be dropped)
|
|
270
|
+
assert [c.header for c in table.columns] == ["emailaddress", "quota", "domain"]
|
|
271
271
|
|
|
272
272
|
|
|
273
273
|
def test_render_kv_drops_empty_and_nests_objects(capsys):
|
|
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
|