certmate-cli 0.1.3__tar.gz → 0.1.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.
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/.gitignore +5 -0
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/PKG-INFO +3 -3
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/certmate_cli/__init__.py +1 -1
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/certmate_cli/main.py +59 -6
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/pyproject.toml +7 -4
- {certmate_cli-0.1.3 → certmate_cli-0.1.5}/README.md +0 -0
|
@@ -79,6 +79,7 @@ htmlcov/
|
|
|
79
79
|
.pytest_cache/
|
|
80
80
|
.coverage
|
|
81
81
|
coverage.xml
|
|
82
|
+
coverage.json
|
|
82
83
|
test_results.json
|
|
83
84
|
|
|
84
85
|
# Local dev / debug scripts (kept on developer machines only)
|
|
@@ -114,3 +115,7 @@ theme-baseline/
|
|
|
114
115
|
UI_DRACONIAN_ANALYSIS.md
|
|
115
116
|
UI_UX_Opinioni_CertMate.pdf
|
|
116
117
|
UI_REDESIGN_PLAN.md
|
|
118
|
+
|
|
119
|
+
# Local nginx reverse-proxy config: copy nginx.conf.example to nginx.conf and
|
|
120
|
+
# fill in your domain. The copy is yours; the example is tracked (#576).
|
|
121
|
+
nginx.conf
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: certmate-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: CertMate command-line interface — the SSL certificate lifecycle from your terminal
|
|
5
5
|
Project-URL: Homepage, https://github.com/fabriziosalmi/certmate
|
|
6
6
|
Project-URL: Source, https://github.com/fabriziosalmi/certmate/tree/main/clients/certmate-cli
|
|
@@ -23,7 +23,7 @@ Classifier: Topic :: Security
|
|
|
23
23
|
Classifier: Topic :: System :: Systems Administration
|
|
24
24
|
Classifier: Topic :: Utilities
|
|
25
25
|
Requires-Python: >=3.9
|
|
26
|
-
Requires-Dist: certmate-sdk>=0.1.
|
|
26
|
+
Requires-Dist: certmate-sdk>=0.1.5
|
|
27
27
|
Requires-Dist: rich>=13
|
|
28
28
|
Requires-Dist: typer>=0.9
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""certmate-cli — the CertMate SSL lifecycle from your terminal (built on certmate-sdk)."""
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.5"
|
|
@@ -39,6 +39,24 @@ app.add_typer(deploy_app, name="deploy")
|
|
|
39
39
|
out = Console()
|
|
40
40
|
err = Console(stderr=True)
|
|
41
41
|
|
|
42
|
+
|
|
43
|
+
def _version_callback(value: bool) -> None:
|
|
44
|
+
"""`--version` prints the version and exits 0, before anything else runs.
|
|
45
|
+
|
|
46
|
+
It has to be eager: the flag must work with no server configured, no
|
|
47
|
+
token, and no network — reporting which build you have is the first thing
|
|
48
|
+
anyone does when something is wrong.
|
|
49
|
+
"""
|
|
50
|
+
if value:
|
|
51
|
+
from certmate_cli import __version__
|
|
52
|
+
|
|
53
|
+
# Plain print, not `out.print`: a version string gets piped and
|
|
54
|
+
# compared, so it must not pick up Rich's wrapping or markup.
|
|
55
|
+
print(__version__)
|
|
56
|
+
raise typer.Exit(0)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
42
60
|
# A lax hostname/wildcard check for the client-side --dry-run preflight; the
|
|
43
61
|
# server is the real authority, this just catches obvious typos before we
|
|
44
62
|
# spend an API call.
|
|
@@ -71,6 +89,13 @@ def _main(
|
|
|
71
89
|
help="API bearer token. Prefer the CERTMATE_TOKEN "
|
|
72
90
|
"environment variable: --token is visible to other "
|
|
73
91
|
"local processes (ps) and shell history."),
|
|
92
|
+
# Lives on THIS callback rather than a second one: Typer keeps only one
|
|
93
|
+
# root callback, so a separate `@app.callback()` silently replaces this
|
|
94
|
+
# whole function — including the --token warning above.
|
|
95
|
+
version: Optional[bool] = typer.Option(None, "--version", "-V",
|
|
96
|
+
callback=_version_callback,
|
|
97
|
+
is_eager=True,
|
|
98
|
+
help="Show the certmate-cli version and exit."),
|
|
74
99
|
):
|
|
75
100
|
# Kept for compatibility, but discourage --token interactively: argv is
|
|
76
101
|
# world-readable via ps and lands in shell history. Warn only on a TTY so
|
|
@@ -141,11 +166,31 @@ def cert_ls(ctx: typer.Context):
|
|
|
141
166
|
table.add_column("DAYS", justify="right")
|
|
142
167
|
table.add_column("CA")
|
|
143
168
|
table.add_column("AUTO-RENEW")
|
|
144
|
-
|
|
169
|
+
# Sort by seconds where the server sends them: a certificate with 23 hours
|
|
170
|
+
# left and one that lapsed an hour ago are both 0 or -1 in whole days, and
|
|
171
|
+
# would otherwise land next to each other in either order.
|
|
172
|
+
def _remaining(cert):
|
|
173
|
+
if cert.seconds_left is not None:
|
|
174
|
+
return cert.seconds_left
|
|
175
|
+
if cert.days_until_expiry is not None:
|
|
176
|
+
return cert.days_until_expiry * 86400
|
|
177
|
+
return 1 << 40
|
|
178
|
+
|
|
179
|
+
for c in sorted(certs, key=_remaining):
|
|
145
180
|
days = c.days_until_expiry
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
181
|
+
expired = c.has_expired()
|
|
182
|
+
# "0" for a certificate with 23 hours left was read as expired by
|
|
183
|
+
# everything that saw it, including CertMate's own dashboard until
|
|
184
|
+
# server 2.32.2. Say which of the two it is instead of printing the
|
|
185
|
+
# number that cannot tell them apart.
|
|
186
|
+
if expired is True:
|
|
187
|
+
days_str, colour = "expired", "red"
|
|
188
|
+
elif days is None:
|
|
189
|
+
days_str, colour = "-", "green"
|
|
190
|
+
elif days == 0:
|
|
191
|
+
days_str, colour = ("<1" if expired is False else "?"), "red"
|
|
192
|
+
else:
|
|
193
|
+
days_str = str(days)
|
|
149
194
|
colour = "red" if days < 7 else ("yellow" if days < 30 else "green")
|
|
150
195
|
table.add_row(
|
|
151
196
|
c.domain,
|
|
@@ -162,8 +207,16 @@ def cert_info(ctx: typer.Context, domain: str):
|
|
|
162
207
|
"""Show a certificate's details."""
|
|
163
208
|
c = _run(lambda: _client(ctx).get_certificate(domain))
|
|
164
209
|
out.print(f"[bold]{c.domain}[/]")
|
|
165
|
-
|
|
166
|
-
|
|
210
|
+
if c.has_expired() is True:
|
|
211
|
+
remaining = "[red]expired[/]"
|
|
212
|
+
elif c.days_until_expiry is None:
|
|
213
|
+
remaining = "? days"
|
|
214
|
+
elif c.days_until_expiry == 0:
|
|
215
|
+
# Under a day, and not expired, or the server is too old to say.
|
|
216
|
+
remaining = "less than a day" if c.has_expired() is False else "? days"
|
|
217
|
+
else:
|
|
218
|
+
remaining = f"{c.days_until_expiry} days"
|
|
219
|
+
out.print(f" expires: {c.expiry_date or '-'} ({remaining})")
|
|
167
220
|
out.print(f" CA: {c.ca_provider or '-'}")
|
|
168
221
|
out.print(f" DNS: {c.dns_provider or '-'}")
|
|
169
222
|
out.print(f" auto-renew: {c.auto_renew}")
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "certmate-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "CertMate command-line interface — the SSL certificate lifecycle from your terminal"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -30,10 +30,13 @@ classifiers = [
|
|
|
30
30
|
]
|
|
31
31
|
# Built ON the SDK (never the reverse). typer for the command surface, rich
|
|
32
32
|
# for tables/spinners. Still light — no server deps.
|
|
33
|
-
# The SDK floor tracks the CLI release
|
|
34
|
-
#
|
|
33
|
+
# The SDK floor tracks the CLI release, and now something enforces that:
|
|
34
|
+
# tests/test_version_consistency.py fails if this floor falls behind the SDK
|
|
35
|
+
# in the tree. It had already drifted once, sitting at 0.1.3 while both
|
|
36
|
+
# packages were 0.1.4. 0.1.5 is needed for Certificate.has_expired(), which
|
|
37
|
+
# `cert ls` and `cert info` call on every row.
|
|
35
38
|
dependencies = [
|
|
36
|
-
"certmate-sdk>=0.1.
|
|
39
|
+
"certmate-sdk>=0.1.5",
|
|
37
40
|
"typer>=0.9",
|
|
38
41
|
"rich>=13",
|
|
39
42
|
]
|
|
File without changes
|