devnomads-cli 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/PKG-INFO +4 -7
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/README.md +2 -3
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/PKG-INFO +4 -7
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/requires.txt +1 -4
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/dncli.py +12 -10
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/pyproject.toml +2 -5
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_cert.py +2 -2
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_config.py +2 -2
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/LICENSE +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/SOURCES.txt +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/dependency_links.txt +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/entry_points.txt +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/devnomads_cli.egg-info/top_level.txt +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/setup.cfg +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_cli.py +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_generate.py +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_generated_cli.py +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_helpers.py +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_hook.py +0 -0
- {devnomads_cli-0.3.0 → devnomads_cli-0.4.0}/tests/test_transfer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devnomads-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Manage your DevNomads services from the command line
|
|
5
5
|
Author-email: DevNomads <support@devnomads.nl>
|
|
6
6
|
License: MIT
|
|
@@ -11,9 +11,7 @@ Requires-Dist: typer>=0.12
|
|
|
11
11
|
Requires-Dist: httpx>=0.27
|
|
12
12
|
Requires-Dist: rich>=13
|
|
13
13
|
Requires-Dist: cryptography>=42
|
|
14
|
-
Requires-Dist: devnomads>=0.1
|
|
15
|
-
Provides-Extra: cert
|
|
16
|
-
Requires-Dist: devnomads[acme]>=0.1; extra == "cert"
|
|
14
|
+
Requires-Dist: devnomads[acme]>=0.2.1
|
|
17
15
|
Dynamic: license-file
|
|
18
16
|
|
|
19
17
|
# dncli
|
|
@@ -56,7 +54,7 @@ Sleutels**, then store it:
|
|
|
56
54
|
dncli configure
|
|
57
55
|
```
|
|
58
56
|
|
|
59
|
-
The key is written to `~/.config/
|
|
57
|
+
The key is written to `~/.config/dncli/credentials`, readable only
|
|
60
58
|
by you. From here every command works:
|
|
61
59
|
|
|
62
60
|
```sh
|
|
@@ -128,10 +126,9 @@ dncli services list | jq -r '.[].entity'
|
|
|
128
126
|
|
|
129
127
|
## Certificates
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
`dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
|
|
132
130
|
|
|
133
131
|
```sh
|
|
134
|
-
uv tool install "devnomads-cli[cert]"
|
|
135
132
|
dncli cert issue example.com -d "*.example.com"
|
|
136
133
|
```
|
|
137
134
|
|
|
@@ -38,7 +38,7 @@ Sleutels**, then store it:
|
|
|
38
38
|
dncli configure
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
The key is written to `~/.config/
|
|
41
|
+
The key is written to `~/.config/dncli/credentials`, readable only
|
|
42
42
|
by you. From here every command works:
|
|
43
43
|
|
|
44
44
|
```sh
|
|
@@ -110,10 +110,9 @@ dncli services list | jq -r '.[].entity'
|
|
|
110
110
|
|
|
111
111
|
## Certificates
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
`dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
|
|
114
114
|
|
|
115
115
|
```sh
|
|
116
|
-
uv tool install "devnomads-cli[cert]"
|
|
117
116
|
dncli cert issue example.com -d "*.example.com"
|
|
118
117
|
```
|
|
119
118
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devnomads-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Manage your DevNomads services from the command line
|
|
5
5
|
Author-email: DevNomads <support@devnomads.nl>
|
|
6
6
|
License: MIT
|
|
@@ -11,9 +11,7 @@ Requires-Dist: typer>=0.12
|
|
|
11
11
|
Requires-Dist: httpx>=0.27
|
|
12
12
|
Requires-Dist: rich>=13
|
|
13
13
|
Requires-Dist: cryptography>=42
|
|
14
|
-
Requires-Dist: devnomads>=0.1
|
|
15
|
-
Provides-Extra: cert
|
|
16
|
-
Requires-Dist: devnomads[acme]>=0.1; extra == "cert"
|
|
14
|
+
Requires-Dist: devnomads[acme]>=0.2.1
|
|
17
15
|
Dynamic: license-file
|
|
18
16
|
|
|
19
17
|
# dncli
|
|
@@ -56,7 +54,7 @@ Sleutels**, then store it:
|
|
|
56
54
|
dncli configure
|
|
57
55
|
```
|
|
58
56
|
|
|
59
|
-
The key is written to `~/.config/
|
|
57
|
+
The key is written to `~/.config/dncli/credentials`, readable only
|
|
60
58
|
by you. From here every command works:
|
|
61
59
|
|
|
62
60
|
```sh
|
|
@@ -128,10 +126,9 @@ dncli services list | jq -r '.[].entity'
|
|
|
128
126
|
|
|
129
127
|
## Certificates
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
`dncli` issues Let's Encrypt certificates over DNS-01 and HTTP-01:
|
|
132
130
|
|
|
133
131
|
```sh
|
|
134
|
-
uv tool install "devnomads-cli[cert]"
|
|
135
132
|
dncli cert issue example.com -d "*.example.com"
|
|
136
133
|
```
|
|
137
134
|
|
|
@@ -44,6 +44,7 @@ from devnomads.api import DevNomadsError
|
|
|
44
44
|
from devnomads.api.client import _unwrap as _lib_unwrap
|
|
45
45
|
from devnomads.dns import Dns, challenge_name
|
|
46
46
|
from rich.console import Console
|
|
47
|
+
from rich.markup import escape
|
|
47
48
|
from rich.table import Table
|
|
48
49
|
from typer.core import TyperGroup
|
|
49
50
|
|
|
@@ -71,7 +72,7 @@ class CliError(typer.Exit):
|
|
|
71
72
|
|
|
72
73
|
def __init__(self, message: str) -> None:
|
|
73
74
|
# soft_wrap keeps the error a single grep-able line
|
|
74
|
-
err_console.print(f"[red]error:[/] {message}", soft_wrap=True)
|
|
75
|
+
err_console.print(f"[red]error:[/] {escape(message)}", soft_wrap=True)
|
|
75
76
|
self.message = message
|
|
76
77
|
super().__init__(code=1)
|
|
77
78
|
|
|
@@ -85,7 +86,7 @@ def config_dir() -> Path:
|
|
|
85
86
|
return Path(env_dir)
|
|
86
87
|
xdg = os.environ.get("XDG_CONFIG_HOME")
|
|
87
88
|
base = Path(xdg) if xdg else Path.home() / ".config"
|
|
88
|
-
return base / "
|
|
89
|
+
return base / "dncli"
|
|
89
90
|
|
|
90
91
|
|
|
91
92
|
def credentials_path() -> Path:
|
|
@@ -1275,10 +1276,12 @@ def _hook_dispatch(dns: Dns, operation: str, args: list[str]) -> int:
|
|
|
1275
1276
|
else:
|
|
1276
1277
|
dns.unset_txt(record, token_value)
|
|
1277
1278
|
except (AuthError, ApiError) as exc:
|
|
1278
|
-
err_console.print(
|
|
1279
|
+
err_console.print(
|
|
1280
|
+
f"[red]error:[/] {escape(_error_message(exc.status, exc.detail))}"
|
|
1281
|
+
)
|
|
1279
1282
|
return 1
|
|
1280
1283
|
except DevNomadsError as exc:
|
|
1281
|
-
err_console.print(f"[red]error:[/] {exc}")
|
|
1284
|
+
err_console.print(f"[red]error:[/] {escape(str(exc))}")
|
|
1282
1285
|
return 1
|
|
1283
1286
|
return 0
|
|
1284
1287
|
|
|
@@ -1306,7 +1309,7 @@ def hook_main(argv: list[str] | None = None) -> int:
|
|
|
1306
1309
|
try:
|
|
1307
1310
|
client = ApiClient.from_environment()
|
|
1308
1311
|
except DevNomadsError as exc:
|
|
1309
|
-
err_console.print(f"[red]error:[/] {exc}")
|
|
1312
|
+
err_console.print(f"[red]error:[/] {escape(str(exc))}")
|
|
1310
1313
|
return 1
|
|
1311
1314
|
try:
|
|
1312
1315
|
return _hook_dispatch(Dns(client), operation, argv[2:])
|
|
@@ -1360,16 +1363,15 @@ CERT_RENEW_WINDOW_DAYS = 30
|
|
|
1360
1363
|
|
|
1361
1364
|
|
|
1362
1365
|
def _load_acme() -> Any:
|
|
1363
|
-
"""Import devnomads.acme lazily,
|
|
1364
|
-
|
|
1366
|
+
"""Import devnomads.acme lazily, so non-cert commands skip the ACME
|
|
1367
|
+
stack at startup."""
|
|
1365
1368
|
|
|
1366
1369
|
try:
|
|
1367
1370
|
import devnomads.acme as acme
|
|
1368
1371
|
except ImportError as exc:
|
|
1369
1372
|
raise CliError(
|
|
1370
|
-
"
|
|
1371
|
-
'pip install "devnomads-cli
|
|
1372
|
-
'(or: uv tool install "devnomads-cli[cert]")'
|
|
1373
|
+
"could not import devnomads.acme; the install looks broken - "
|
|
1374
|
+
'reinstall with: pip install --force-reinstall "devnomads-cli"'
|
|
1373
1375
|
) from exc
|
|
1374
1376
|
return acme
|
|
1375
1377
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "devnomads-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "Manage your DevNomads services from the command line"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -11,12 +11,9 @@ dependencies = [
|
|
|
11
11
|
"httpx>=0.27",
|
|
12
12
|
"rich>=13",
|
|
13
13
|
"cryptography>=42",
|
|
14
|
-
"devnomads>=0.1",
|
|
14
|
+
"devnomads[acme]>=0.2.1",
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
[project.optional-dependencies]
|
|
18
|
-
cert = ["devnomads[acme]>=0.1"]
|
|
19
|
-
|
|
20
17
|
[project.scripts]
|
|
21
18
|
dncli = "dncli:run"
|
|
22
19
|
dncli-dns-hook = "dncli:hook_main"
|
|
@@ -119,7 +119,7 @@ def test_issue_out_dir_override(configured, captured, isolated_config, tmp_path)
|
|
|
119
119
|
assert (out / "fullchain.pem").read_text() == FULLCHAIN
|
|
120
120
|
|
|
121
121
|
|
|
122
|
-
def
|
|
122
|
+
def test_load_acme_import_error_message(monkeypatch):
|
|
123
123
|
import builtins
|
|
124
124
|
|
|
125
125
|
real_import = builtins.__import__
|
|
@@ -132,7 +132,7 @@ def test_load_acme_missing_extra_message(monkeypatch):
|
|
|
132
132
|
monkeypatch.setattr(builtins, "__import__", fake_import)
|
|
133
133
|
result = runner.invoke(app, ["cert", "issue", "example.com"])
|
|
134
134
|
assert result.exit_code == 1
|
|
135
|
-
assert "
|
|
135
|
+
assert "devnomads.acme" in result.output
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
def test_renew_skips_valid_cert(configured, captured, isolated_config):
|
|
@@ -16,14 +16,14 @@ def test_config_dir_from_env(isolated_config):
|
|
|
16
16
|
def test_config_dir_xdg_fallback(monkeypatch, tmp_path):
|
|
17
17
|
monkeypatch.delenv(dncli.ENV_CONFIG_DIR, raising=False)
|
|
18
18
|
monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "xdg"))
|
|
19
|
-
assert dncli.config_dir() == tmp_path / "xdg" / "
|
|
19
|
+
assert dncli.config_dir() == tmp_path / "xdg" / "dncli"
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def test_config_dir_home_fallback(monkeypatch, tmp_path):
|
|
23
23
|
monkeypatch.delenv(dncli.ENV_CONFIG_DIR, raising=False)
|
|
24
24
|
monkeypatch.delenv("XDG_CONFIG_HOME", raising=False)
|
|
25
25
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
26
|
-
assert dncli.config_dir() == tmp_path / ".config" / "
|
|
26
|
+
assert dncli.config_dir() == tmp_path / ".config" / "dncli"
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def test_save_credentials_sets_strict_permissions(write_profile):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|