feat:
--ADDED security to apis --MARKED DONE to integrated apis
This commit is contained in:
1 parent
f43eaee98f
commit
3be2f2b0ce
3 files changed
+127
-12
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import uvicorn
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import FastAPI,Depends, Header, HTTPException, status, WebSocket, WebSocketDisconnect
|
||||
from fastapi import FastAPI,Depends, Header, HTTPException, status, WebSocket, WebSocketDisconnect, WebSocketException
|
||||
import psycopg2
|
||||
from jwt import ExpiredSignatureError, InvalidTokenError
|
||||
import jwt
|
||||
@@ -89,8 +89,42 @@ def verify_token(
|
||||
)
|
||||
|
||||
|
||||
# JWT TOKEN VERIFICATION FOR WEBSOCKET CONNECTIONS
|
||||
async def verify_websocket_token(websocket: WebSocket):
|
||||
|
||||
token = websocket.query_params.get("token")
|
||||
|
||||
if not token:
|
||||
raise WebSocketException(
|
||||
code=status.WS_1008_POLICY_VIOLATION,
|
||||
reason="Authentication token missing"
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
payload = jwt.decode(
|
||||
token,
|
||||
SECRET_KEY,
|
||||
algorithms=[ALGORITHM],
|
||||
)
|
||||
|
||||
return payload
|
||||
|
||||
except ExpiredSignatureError:
|
||||
|
||||
|
||||
raise WebSocketException(
|
||||
code=status.WS_1008_POLICY_VIOLATION,
|
||||
reason="Token expired"
|
||||
)
|
||||
|
||||
except InvalidTokenError:
|
||||
|
||||
|
||||
raise WebSocketException(
|
||||
code=status.WS_1008_POLICY_VIOLATION,
|
||||
reason="Invalid token"
|
||||
)
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -215,9 +249,12 @@ def get_replication_health(data: NodeStatusRequest):
|
||||
# "user": "postgres",
|
||||
# "password": "postgres"
|
||||
# }
|
||||
|
||||
#DONE
|
||||
@app.websocket("/ws/node/replication-health")
|
||||
async def replication_monitor(websocket: WebSocket):
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
# if token_data is None:
|
||||
# return
|
||||
await websocket.accept()
|
||||
try:
|
||||
raw_data = await websocket.receive_json()
|
||||
@@ -344,10 +381,12 @@ def get_database_uptime(
|
||||
if conn:
|
||||
conn.close()
|
||||
|
||||
|
||||
# DONE
|
||||
@app.websocket("/ws/database/status")
|
||||
async def database_status_monitor(websocket: WebSocket):
|
||||
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
# if token_data is None:
|
||||
# return
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
@@ -508,9 +547,12 @@ def get_connection_usage(data: DatabaseRequest):
|
||||
conn.close()
|
||||
|
||||
# WEB SOCKETS FOR ACTIVE CONNECTIONS MONITORING
|
||||
# DONE
|
||||
@app.websocket("/ws/database/active-connections")
|
||||
async def database_active_connections_monitor(websocket: WebSocket):
|
||||
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
# if token_data is None:
|
||||
# return
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
@@ -725,9 +767,12 @@ def get_cache_hit_ratio(data: DatabaseRequest):
|
||||
conn.close()
|
||||
|
||||
#TPS AND CACHE HIT RATIO WEB SOCKET
|
||||
# DONE
|
||||
@app.websocket("/ws/database/performance")
|
||||
async def database_performance_monitor(websocket: WebSocket):
|
||||
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
# if token_data is None:
|
||||
# return
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
@@ -911,7 +956,9 @@ def get_database_deadlocks(data: DatabaseRequest):
|
||||
# LOCKS AND DEADLOCKS WEB SOCKET
|
||||
@app.websocket("/ws/database/locks-deadlocks")
|
||||
async def database_locks_deadlocks_monitor(websocket: WebSocket):
|
||||
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
# if token_data is None:
|
||||
# return
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
@@ -1040,6 +1087,7 @@ def get_database_size(data: DatabaseRequest):
|
||||
|
||||
|
||||
# API ENDPOINTS FOR DATABASE SIZE
|
||||
#DONE
|
||||
@app.post("/database/size")
|
||||
def database_size(
|
||||
data: DatabaseRequest,
|
||||
@@ -1136,6 +1184,7 @@ def get_largest_tables(
|
||||
|
||||
|
||||
# SHOWS THE LIST OF TABLES IN THE DATABASE SORTED BY SIZE
|
||||
# DONE
|
||||
@app.post("/database/largest-tables")
|
||||
def database_largest_tables(
|
||||
data: DatabaseRequest,
|
||||
@@ -1216,6 +1265,7 @@ def get_index_size(data: DatabaseRequest):
|
||||
|
||||
|
||||
# API ENDPOINT FOR INDEX SIZE REST API
|
||||
# DONE
|
||||
@app.post("/database/index-size")
|
||||
def database_index_size(
|
||||
data: DatabaseRequest,
|
||||
@@ -1338,9 +1388,12 @@ def get_tuple_reads_writes(data: DatabaseRequest):
|
||||
conn.close()
|
||||
|
||||
# TUPLE READS AND WRITES PER SECOND WEB SOCKET
|
||||
# DONE
|
||||
@app.websocket("/ws/database/tuple-activity")
|
||||
async def database_tuple_activity_monitor(websocket: WebSocket):
|
||||
|
||||
token_data = await verify_websocket_token(websocket)
|
||||
if token_data is None:
|
||||
return
|
||||
await websocket.accept()
|
||||
|
||||
try:
|
||||
@@ -1429,11 +1482,25 @@ def get_dead_tuples(data: DatabaseRequest):
|
||||
n_live_tup,
|
||||
n_dead_tup,
|
||||
last_vacuum,
|
||||
last_autovacuum
|
||||
last_autovacuum,
|
||||
|
||||
pg_total_relation_size(
|
||||
quote_ident(schemaname) || '.' ||
|
||||
quote_ident(relname)
|
||||
) AS size_bytes,
|
||||
|
||||
ROUND(
|
||||
pg_total_relation_size(
|
||||
quote_ident(schemaname) || '.' ||
|
||||
quote_ident(relname)
|
||||
)::numeric
|
||||
/ 1024 / 1024,
|
||||
2
|
||||
) AS size_mb
|
||||
|
||||
FROM pg_stat_user_tables
|
||||
WHERE n_dead_tup > 0
|
||||
ORDER BY n_dead_tup DESC;
|
||||
|
||||
ORDER BY size_bytes DESC;
|
||||
""")
|
||||
|
||||
rows = cursor.fetchall()
|
||||
@@ -1443,17 +1510,40 @@ def get_dead_tuples(data: DatabaseRequest):
|
||||
for row in rows
|
||||
)
|
||||
|
||||
total_size_bytes = sum(
|
||||
row["size_bytes"] or 0
|
||||
for row in rows
|
||||
)
|
||||
|
||||
total_size_mb = round(
|
||||
total_size_bytes / 1024 / 1024,
|
||||
2
|
||||
)
|
||||
|
||||
return {
|
||||
"database_name": data.dbname,
|
||||
|
||||
"table_count": len(rows),
|
||||
|
||||
"total_dead_tuples": total_dead_tuples,
|
||||
|
||||
"total_table_size_bytes": total_size_bytes,
|
||||
"total_table_size_mb": total_size_mb,
|
||||
|
||||
"tables": [
|
||||
{
|
||||
"schema": row["schemaname"],
|
||||
|
||||
"table_name": row["table_name"],
|
||||
|
||||
"live_tuples": row["n_live_tup"],
|
||||
|
||||
"dead_tuples": row["n_dead_tup"],
|
||||
|
||||
"size_bytes": row["size_bytes"],
|
||||
|
||||
"size_mb": float(row["size_mb"]),
|
||||
|
||||
"last_vacuum":
|
||||
row["last_vacuum"].isoformat()
|
||||
if row["last_vacuum"]
|
||||
@@ -1472,8 +1562,17 @@ def get_dead_tuples(data: DatabaseRequest):
|
||||
|
||||
return {
|
||||
"database_name": data.dbname,
|
||||
|
||||
"table_count": None,
|
||||
|
||||
"total_dead_tuples": None,
|
||||
|
||||
"total_table_size_bytes": None,
|
||||
|
||||
"total_table_size_mb": None,
|
||||
|
||||
"tables": [],
|
||||
|
||||
"error": str(e)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user