Skip to content

Commit 794ae6f

Browse files
committed
Add health check for database connection
Signed-off-by: Anja Strunk <[email protected]>
1 parent 846a1a7 commit 794ae6f

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

compliance-monitor/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ services:
2828
- SCM_DB_HOST=postgres
2929
- SCM_DB_PORT=5432
3030
- SCM_DB_PASSWORD_FILE=/run/secrets/db_password
31+
- SCM_HC_USER=healthz
32+
- SCM_HC_PASSWORD=healthzpassword
3133
- SCM_BASE_URL=https://compliance.sovereignit.cloud/
3234
volumes:
3335
- ../Tests:/Tests

compliance-monitor/monitor.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def __init__(self):
6464
self.db_host = os.getenv("SCM_DB_HOST", "localhost")
6565
self.db_port = os.getenv("SCM_DB_PORT", 5432)
6666
self.db_user = os.getenv("SCM_DB_USER", "postgres")
67+
self.hc_user = os.getenv("SCM_HC_USER", "healthz")
68+
self.hc_password = os.getenv("SCM_HC_PASSWORD", "healthzpassword")
6769
password_file_path = os.getenv("SCM_DB_PASSWORD_FILE", None)
6870
if password_file_path:
6971
with open(os.path.abspath(password_file_path), "r") as fileobj:
@@ -123,6 +125,7 @@ class ViewType(Enum):
123125
# do I hate these globals, but I don't see another way with these frameworks
124126
app = FastAPI()
125127
security = HTTPBasic(realm="Compliance monitor", auto_error=True) # use False for optional login
128+
optional_security = HTTPBasic(realm="Compliance monitor", auto_error=False)
126129
settings = Settings()
127130
# see https://passlib.readthedocs.io/en/stable/narr/quickstart.html
128131
cryptctx = CryptContext(
@@ -719,6 +722,39 @@ async def post_results(
719722
conn.commit()
720723

721724

725+
@app.get("/healthz")
726+
async def get_healthz(
727+
request: Request,
728+
):
729+
"""return monitor's health status"""
730+
credentials = await optional_security(request)
731+
732+
# check credentials
733+
if credentials is None:
734+
# no credentials were set
735+
check_db_connection()
736+
elif credentials.username == settings.hc_user and credentials.password == settings.hc_password:
737+
# healthz user
738+
check_db_connection(authorized=True)
739+
else:
740+
# unauthorized user
741+
check_db_connection()
742+
743+
return {"message": "OK"}
744+
745+
def check_db_connection(authorized: bool = False):
746+
# check database connection
747+
try:
748+
mk_conn(settings=settings)
749+
except psycopg2.OperationalError as e:
750+
if authorized:
751+
# authorized user
752+
raise HTTPException(status_code=500,
753+
detail="Database Connection Error. " + e.args[0].capitalize())
754+
else:
755+
raise HTTPException(status_code=500, detail="Internal Server Error")
756+
757+
722758
def pick_filter(results, subject, scope):
723759
"""Jinja filter to pick scope results from `results` for given `subject` and `scope`"""
724760
return results.get(subject, {}).get(scope, {})

0 commit comments

Comments
 (0)