From 6e4be8965d7368e1268756f18d1f92d909ba158f Mon Sep 17 00:00:00 2001 From: Vlad Doloman Date: Wed, 24 Jun 2026 03:25:42 +0300 Subject: [PATCH] feat: add two-digit counter suffix to vpn-configs dir (CN_YYYY-MM-DD_NN) --- openvpncertupdate.py | 11 +++++++- tests/test_config_builder.py | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/openvpncertupdate.py b/openvpncertupdate.py index 366a8b3..812477b 100644 --- a/openvpncertupdate.py +++ b/openvpncertupdate.py @@ -271,7 +271,16 @@ def build_ovpn( template_content = Path(template_path).read_text() inline_content = Path(inline_path).read_text() today = date.today().strftime("%Y-%m-%d") - out_dir = Path(output_base_dir) / f"{cn}_{today}" + prefix = f"{cn}_{today}_" + base = Path(output_base_dir) + existing = [ + int(d.name[len(prefix):]) + for d in base.iterdir() + if d.is_dir() and d.name.startswith(prefix) + and d.name[len(prefix):].isdigit() and len(d.name[len(prefix):]) == 2 + ] if base.exists() else [] + next_n = max(existing) + 1 if existing else 0 + out_dir = base / f"{prefix}{next_n:02d}" out_dir.mkdir(parents=True, exist_ok=True) out_file = out_dir / config_name out_file.write_text(template_content + "\n" + inline_content) diff --git a/tests/test_config_builder.py b/tests/test_config_builder.py index 22a60e1..ea472ca 100644 --- a/tests/test_config_builder.py +++ b/tests/test_config_builder.py @@ -26,3 +26,57 @@ def test_output_path_has_cn_and_date(tmp_path): result = build_ovpn("bob", pki, str(tmpl), str(tmp_path / "out"), "vpn.ovpn") assert f"bob_{today}" in result assert result.endswith("vpn.ovpn") + + +def test_first_issuance_uses_counter_00(tmp_path): + pki = setup_pki(tmp_path, "carol") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + result = build_ovpn("carol", pki, str(tmpl), str(tmp_path / "out"), "vpn.ovpn") + assert f"carol_{today}_00" in result + + +def test_second_issuance_same_day_uses_counter_01(tmp_path): + pki = setup_pki(tmp_path, "dave") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + out = str(tmp_path / "out") + build_ovpn("dave", pki, str(tmpl), out, "vpn.ovpn") + result2 = build_ovpn("dave", pki, str(tmpl), out, "vpn.ovpn") + assert f"dave_{today}_01" in result2 + + +def test_counter_skips_to_max_plus_one(tmp_path): + """If _00 and _02 already exist (gap), next counter is 03, not 01.""" + pki = setup_pki(tmp_path, "eve") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + out = tmp_path / "out" + (out / f"eve_{today}_00").mkdir(parents=True) + (out / f"eve_{today}_02").mkdir(parents=True) + result = build_ovpn("eve", pki, str(tmpl), str(out), "vpn.ovpn") + assert f"eve_{today}_03" in result + + +def test_different_cn_same_day_does_not_affect_counter(tmp_path): + pki_a = setup_pki(tmp_path / "a", "alice") + pki_b = setup_pki(tmp_path / "b", "bob") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + out = str(tmp_path / "out") + build_ovpn("alice", str(tmp_path / "a" / "pki"), str(tmpl), out, "vpn.ovpn") + result = build_ovpn("bob", str(tmp_path / "b" / "pki"), str(tmpl), out, "vpn.ovpn") + assert f"bob_{today}_00" in result + + +def test_next_day_counter_resets_to_00(tmp_path): + """Directories from a different date don't affect today's counter.""" + pki = setup_pki(tmp_path, "frank") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + out = tmp_path / "out" + # Simulate yesterday's directories already present + (out / "frank_2000-01-01_00").mkdir(parents=True) + (out / "frank_2000-01-01_05").mkdir(parents=True) + result = build_ovpn("frank", pki, str(tmpl), str(out), "vpn.ovpn") + assert f"frank_{today}_00" in result