Add --days CLI flag overriding CERT_DAYS

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Vlad Doloman
2026-08-15 05:22:58 +03:00
parent 2e98155b5f
commit 54f3e300a5
2 changed files with 72 additions and 1 deletions

View File

@@ -1530,7 +1530,7 @@ class CliRunner:
print(f"Building certificate for {cn}", file=sys.stderr)
try:
build_client_full(EASYRSA_DIR, EASYRSA_PKI_DIR, cn, password, CA_PASSPHRASE,
email=email_addr)
email=email_addr, days=CERT_DAYS)
except EasyRSAError as exc:
if revoked:
print(
@@ -1611,6 +1611,9 @@ def _build_parser() -> argparse.ArgumentParser:
group.add_argument("--list-all", action="store_true", help="List all CNs with email")
parser.add_argument("--email", metavar="EMAIL",
help="Email address (required for --create; optional for --reissue)")
parser.add_argument("--days", metavar="N",
help="Certificate lifetime in days for --create/--reissue "
"(overrides CERT_DAYS; omit to use CERT_DAYS)")
parser.add_argument("--send-email", dest="send_email", action="store_const", const=True,
default=None, help="Send email after issuing cert (default unless --show-eml)")
parser.add_argument("--no-send-email", dest="send_email", action="store_const", const=False,
@@ -1640,6 +1643,14 @@ def main() -> None:
sys.exit(1)
globals().update(overrides)
global CERT_DAYS
try:
CERT_DAYS = (resolve_cert_days(args.days, "--days") if args.days is not None
else resolve_cert_days(CERT_DAYS))
except ConfigError as exc:
print(f"error: {exc}", file=sys.stderr)
sys.exit(1)
if args.list:
CliRunner().list_certs(show_all=False)
return

View File

@@ -633,3 +633,63 @@ def test_main_show_eml_send_email_override(monkeypatch):
runner.create.assert_called_once_with(
"alice", "a@b.com", send_email_flag=True, show_eml=True
)
# ---------------------------------------------------------------------------
# --days
# ---------------------------------------------------------------------------
def test_days_flag_parses():
args = _build_parser().parse_args(["--create", "alice", "--email", "a@b.c",
"--days", "90"])
assert args.days == "90"
def test_days_defaults_to_none_when_absent():
args = _build_parser().parse_args(["--create", "alice", "--email", "a@b.c"])
assert args.days is None
def test_issue_passes_resolved_days_to_build_client_full(monkeypatch, capsys):
mocks = _patch_issue(monkeypatch)
monkeypatch.setattr("openvpncertupdate.CERT_DAYS", "90")
CliRunner().create("alice", "alice@example.com")
assert mocks["build_client_full"].call_args.kwargs["days"] == "90"
def test_issue_passes_empty_days_when_inheriting(monkeypatch, capsys):
mocks = _patch_issue(monkeypatch)
monkeypatch.setattr("openvpncertupdate.CERT_DAYS", "")
CliRunner().create("alice", "alice@example.com")
assert mocks["build_client_full"].call_args.kwargs["days"] == ""
def test_main_days_flag_overrides_cert_days(monkeypatch):
import openvpncertupdate
monkeypatch.setattr(sys, "argv",
["prog", "--create", "alice", "--email", "a@b.c", "--days", "30"])
monkeypatch.setattr("openvpncertupdate.CERT_DAYS", "default")
monkeypatch.setattr("openvpncertupdate.resolve_ca_passphrase", MagicMock(return_value=""))
runner = MagicMock()
monkeypatch.setattr("openvpncertupdate.CliRunner", MagicMock(return_value=runner))
main()
assert openvpncertupdate.CERT_DAYS == "30"
def test_main_resolves_cert_days_when_no_flag(monkeypatch):
import openvpncertupdate
monkeypatch.setattr(sys, "argv", ["prog", "--create", "alice", "--email", "a@b.c"])
monkeypatch.setattr("openvpncertupdate.CERT_DAYS", "090")
monkeypatch.setattr("openvpncertupdate.resolve_ca_passphrase", MagicMock(return_value=""))
monkeypatch.setattr("openvpncertupdate.CliRunner", MagicMock(return_value=MagicMock()))
main()
assert openvpncertupdate.CERT_DAYS == "90"
def test_main_rejects_bad_days_flag(monkeypatch, capsys):
monkeypatch.setattr(sys, "argv",
["prog", "--create", "alice", "--email", "a@b.c", "--days", "0"])
monkeypatch.setattr("openvpncertupdate.resolve_ca_passphrase", MagicMock(return_value=""))
with pytest.raises(SystemExit):
main()
assert "--days" in capsys.readouterr().err