chore: prod env checker, secret guidance, internet-exposure runbook
This commit is contained in:
parent
c3c4986979
commit
25cf645295
5 changed files with 219 additions and 4 deletions
79
backend/tests/test_check_prod.py
Normal file
79
backend/tests/test_check_prod.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
"""Prod env checker: failures block deploys, warnings don't."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "backend" / "scripts"))
|
||||
|
||||
from check_prod import check
|
||||
|
||||
|
||||
def _good() -> dict:
|
||||
return {
|
||||
"CALLBACK_TOKEN": "t" * 40,
|
||||
"LANGFLOW_API_KEY": "k" * 24,
|
||||
"LFX_API_KEY": "x" * 24,
|
||||
"LANGFLOW_SUPERUSER_PASSWORD": "p" * 20,
|
||||
"LANGFLOW_SECRET_KEY": "s" * 40,
|
||||
"FRONTEND_MODE": "preview",
|
||||
"ADMIN_EMAILS": "admin@example.com",
|
||||
"SMTP_HOST": "smtp.example.com",
|
||||
"SMTP_PASSWORD": "secret",
|
||||
"CONTACT_TO": "team@example.com",
|
||||
"FRONTEND_URL": "https://example.com",
|
||||
}
|
||||
|
||||
|
||||
def test_good_env_passes_without_warnings():
|
||||
failures, warnings = check(_good())
|
||||
assert failures == []
|
||||
assert warnings == []
|
||||
|
||||
|
||||
def test_empty_and_short_secrets_fail():
|
||||
values = _good()
|
||||
values["CALLBACK_TOKEN"] = ""
|
||||
values["LANGFLOW_SUPERUSER_PASSWORD"] = "short"
|
||||
failures, _ = check(values)
|
||||
assert any("CALLBACK_TOKEN" in f for f in failures)
|
||||
assert any("LANGFLOW_SUPERUSER_PASSWORD" in f for f in failures)
|
||||
|
||||
|
||||
def test_placeholders_fail():
|
||||
values = _good()
|
||||
values["LANGFLOW_API_KEY"] = "sk-"
|
||||
values["LFX_API_KEY"] = "lfx-abc"
|
||||
failures, _ = check(values)
|
||||
assert any("LANGFLOW_API_KEY" in f for f in failures)
|
||||
assert any("LFX_API_KEY" in f for f in failures)
|
||||
|
||||
|
||||
def test_insecure_modes_fail():
|
||||
values = _good()
|
||||
values["FRONTEND_MODE"] = "dev"
|
||||
values["APP_ENV"] = "dev"
|
||||
values["LANGFLOW_AUTO_LOGIN"] = "true"
|
||||
failures, _ = check(values)
|
||||
assert len([f for f in failures if "FRONTEND_MODE" in f]) == 1
|
||||
assert len([f for f in failures if "APP_ENV" in f]) == 1
|
||||
assert len([f for f in failures if "AUTO_LOGIN" in f]) == 1
|
||||
|
||||
|
||||
def test_soft_misconfigurations_warn_only():
|
||||
values = _good()
|
||||
values["ADMIN_EMAILS"] = ""
|
||||
values["SMTP_PASSWORD"] = ""
|
||||
values["CONTACT_TO"] = ""
|
||||
values["FRONTEND_URL"] = "http://example.com"
|
||||
failures, warnings = check(values)
|
||||
assert failures == []
|
||||
assert len(warnings) == 4
|
||||
|
||||
|
||||
def test_example_file_would_not_pass():
|
||||
from check_prod import parse_env
|
||||
|
||||
values = parse_env(REPO_ROOT / ".env.example")
|
||||
failures, _ = check(values)
|
||||
assert failures, "placeholders must be detectable"
|
||||
Loading…
Add table
Add a link
Reference in a new issue