asd
This commit is contained in:
@@ -23,6 +23,7 @@ class ServiceCreate(BaseModel):
|
|||||||
name: str
|
name: str
|
||||||
path: str
|
path: str
|
||||||
git_url: Optional[str] = None
|
git_url: Optional[str] = None
|
||||||
|
alias: Optional[str] = None
|
||||||
|
|
||||||
class ServiceAction(BaseModel):
|
class ServiceAction(BaseModel):
|
||||||
action: str
|
action: str
|
||||||
@@ -215,8 +216,8 @@ async def create_service(service: ServiceCreate):
|
|||||||
raise HTTPException(status_code=404, detail=f"docker-compose file not found in {service_path}")
|
raise HTTPException(status_code=404, detail=f"docker-compose file not found in {service_path}")
|
||||||
|
|
||||||
service_id = await conn.fetchval(
|
service_id = await conn.fetchval(
|
||||||
"INSERT INTO services (name, path, git_url, status) VALUES ($1, $2, $3, $4) RETURNING id",
|
"INSERT INTO services (name, path, git_url, alias, status) VALUES ($1, $2, $3, $4, $5) RETURNING id",
|
||||||
service.name, service_path, service.git_url, "stopped"
|
service.name, service_path, service.git_url, service.alias, "stopped"
|
||||||
)
|
)
|
||||||
|
|
||||||
await log_service_action(conn, service_id, "register", "success", "Service registered")
|
await log_service_action(conn, service_id, "register", "success", "Service registered")
|
||||||
@@ -278,6 +279,36 @@ async def get_service(service_id: int):
|
|||||||
finally:
|
finally:
|
||||||
await release_db(conn)
|
await release_db(conn)
|
||||||
|
|
||||||
|
@app.patch("/services/{service_id}", dependencies=[Depends(verify_token)])
|
||||||
|
async def update_service(service_id: int, updates: dict):
|
||||||
|
"""Update service fields (alias, git_url, etc.)"""
|
||||||
|
conn = await get_db()
|
||||||
|
try:
|
||||||
|
service = await conn.fetchrow("SELECT * FROM services WHERE id = $1", service_id)
|
||||||
|
if not service:
|
||||||
|
raise HTTPException(status_code=404, detail="Service not found")
|
||||||
|
|
||||||
|
# Allowed fields to update
|
||||||
|
allowed_fields = {"alias", "git_url"}
|
||||||
|
update_fields = {k: v for k, v in updates.items() if k in allowed_fields and v is not None}
|
||||||
|
|
||||||
|
if not update_fields:
|
||||||
|
return dict(service)
|
||||||
|
|
||||||
|
# Build dynamic UPDATE query
|
||||||
|
set_clauses = [f"{field} = ${i+1}" for i, field in enumerate(update_fields.keys())]
|
||||||
|
values = list(update_fields.values()) + [service_id]
|
||||||
|
|
||||||
|
await conn.execute(
|
||||||
|
f"UPDATE services SET {', '.join(set_clauses)}, last_updated = ${ len(values)} WHERE id = ${len(values)+1}",
|
||||||
|
*values, datetime.utcnow(), service_id
|
||||||
|
)
|
||||||
|
|
||||||
|
updated_service = await conn.fetchrow("SELECT * FROM services WHERE id = $1", service_id)
|
||||||
|
return dict(updated_service)
|
||||||
|
finally:
|
||||||
|
await release_db(conn)
|
||||||
|
|
||||||
@app.post("/services/{service_id}/action", dependencies=[Depends(verify_token)])
|
@app.post("/services/{service_id}/action", dependencies=[Depends(verify_token)])
|
||||||
async def service_action(service_id: int, action: ServiceAction):
|
async def service_action(service_id: int, action: ServiceAction):
|
||||||
"""Start, stop, or restart a service"""
|
"""Start, stop, or restart a service"""
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS services (
|
|||||||
name VARCHAR(255) NOT NULL UNIQUE,
|
name VARCHAR(255) NOT NULL UNIQUE,
|
||||||
path VARCHAR(512) NOT NULL,
|
path VARCHAR(512) NOT NULL,
|
||||||
git_url VARCHAR(512),
|
git_url VARCHAR(512),
|
||||||
|
alias VARCHAR(255),
|
||||||
status VARCHAR(50) DEFAULT 'stopped',
|
status VARCHAR(50) DEFAULT 'stopped',
|
||||||
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
|||||||
@@ -131,18 +131,26 @@ async def socketio_listener():
|
|||||||
print(f" Sending alert: points {attacker_delta:.2f} >= threshold {ALERT_THRESHOLD_POINTS}")
|
print(f" Sending alert: points {attacker_delta:.2f} >= threshold {ALERT_THRESHOLD_POINTS}")
|
||||||
alert_message = f"🚨 ATTACK DETECTED!\nTeam {attacker_id} stole flag from {service_name}\nPoints lost: {attacker_delta:.2f} FP"
|
alert_message = f"🚨 ATTACK DETECTED!\nTeam {attacker_id} stole flag from {service_name}\nPoints lost: {attacker_delta:.2f} FP"
|
||||||
|
|
||||||
# Get service_id from controller if available
|
# Get service_id from controller by checking name first, then alias
|
||||||
service_id = None
|
service_id = None
|
||||||
try:
|
try:
|
||||||
|
# Try to find service by exact name match
|
||||||
service_row = await conn.fetchrow(
|
service_row = await conn.fetchrow(
|
||||||
"SELECT id FROM services WHERE name = $1 LIMIT 1",
|
"SELECT id FROM services WHERE name = $1 LIMIT 1",
|
||||||
service_name
|
service_name
|
||||||
)
|
)
|
||||||
|
if not service_row:
|
||||||
|
# Try to find service by alias
|
||||||
|
service_row = await conn.fetchrow(
|
||||||
|
"SELECT id FROM services WHERE alias = $1 LIMIT 1",
|
||||||
|
service_name
|
||||||
|
)
|
||||||
|
|
||||||
if service_row:
|
if service_row:
|
||||||
service_id = service_row['id']
|
service_id = service_row['id']
|
||||||
print(f" Found service_id: {service_id} for service: {service_name}")
|
print(f" Found service_id: {service_id} for service: {service_name}")
|
||||||
else:
|
else:
|
||||||
print(f" Service {service_name} not found in services table, buttons will use service_name only")
|
print(f" Service {service_name} not found by name or alias in services table, buttons will use service_name only")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" Error looking up service_id: {e}")
|
print(f" Error looking up service_id: {e}")
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ async def handle_button_click(callback_data: str, chat_id: int, message_id: int)
|
|||||||
# Extract service name from identifier
|
# Extract service name from identifier
|
||||||
service_name = identifier[5:] # Remove 'name_' prefix
|
service_name = identifier[5:] # Remove 'name_' prefix
|
||||||
service_id = None
|
service_id = None
|
||||||
print(f"[BUTTON] Looking up service by name: {service_name}")
|
print(f"[BUTTON] Looking up service by name or alias: {service_name}")
|
||||||
|
|
||||||
# Look up service_id from controller API
|
# Look up service_id from controller API
|
||||||
try:
|
try:
|
||||||
@@ -60,16 +60,17 @@ async def handle_button_click(callback_data: str, chat_id: int, message_id: int)
|
|||||||
print(f"[BUTTON] Controller response: HTTP {resp.status}")
|
print(f"[BUTTON] Controller response: HTTP {resp.status}")
|
||||||
if resp.status == 200:
|
if resp.status == 200:
|
||||||
services = await resp.json()
|
services = await resp.json()
|
||||||
print(f"[BUTTON] Found {len(services)} services: {[s.get('name') for s in services]}")
|
print(f"[BUTTON] Found {len(services)} services")
|
||||||
# Find service by name
|
# Find service by name or alias
|
||||||
for svc in services:
|
for svc in services:
|
||||||
if svc.get('name') == service_name:
|
if svc.get('name') == service_name or svc.get('alias') == service_name:
|
||||||
service_id = svc.get('id')
|
service_id = svc.get('id')
|
||||||
print(f"[BUTTON] Matched service '{service_name}' to ID {service_id}")
|
matched_by = "name" if svc.get('name') == service_name else "alias"
|
||||||
|
print(f"[BUTTON] Matched service '{service_name}' to ID {service_id} (by {matched_by})")
|
||||||
break
|
break
|
||||||
|
|
||||||
if not service_id:
|
if not service_id:
|
||||||
error_msg = f"❌ Service '{service_name}' not registered in controller"
|
error_msg = f"❌ Service '{service_name}' not registered in controller\nPlease add alias in web panel"
|
||||||
print(f"[BUTTON] {error_msg}")
|
print(f"[BUTTON] {error_msg}")
|
||||||
await bot.edit_message_text(
|
await bot.edit_message_text(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user