diff --git a/app/hardening b/app/hardening index fcc3180..30b52e2 100755 --- a/app/hardening +++ b/app/hardening @@ -4,4 +4,7 @@ rex "doas sh -c 'grep -q \"permit nopass 4server as root\" /etc/doas.d/4server.c rex "doas sh -c 'sed -i \"s/^#\?PasswordAuthentication.*/PasswordAuthentication no/\" /etc/ssh/sshd_config'" rex "doas sh -c 'sed -i \"s/^#\?PasswordAuthentication.*/PasswordAuthentication no/\" /etc/ssh/sshd_config.d/50-cloud-init.conf'" + +rex doas apk del linux-virt + rex doas rc-service sshd restart diff --git a/app/sbin/ODOO_19/shell b/app/sbin/ODOO_19/shell new file mode 100755 index 0000000..939af7c --- /dev/null +++ b/app/sbin/ODOO_19/shell @@ -0,0 +1,23 @@ +#!/bin/bash +export PATH=/4PROJECTS/bin:$PATH +if [ ! -n "$1" ]; then + echo "Missing Parameters " + exit 0 +fi + +UUID=$1 +echo "UUID: $UUID" + +source /4server/sbin/helpers + +get_contract_info + + +export ODOO_DB_PASSWORD=$(echo "$SECRET" | jq -r '.psql') + +echo "PASSWORD $ODOO_DB_PASSWORD" + +echo "POSTGRES HOST: $POSTGRES_HOST" + +doas docker exec -it "$UUID" odoo shell --db_host beedb --db_password="$ODOO_DB_PASSWORD" -d "$UUID" --db_user="$UUID" + diff --git a/app/sbin/api b/app/sbin/api index 9547532..7939775 100755 --- a/app/sbin/api +++ b/app/sbin/api @@ -11,6 +11,9 @@ import uvicorn from typing import Dict, Any, Optional from datetime import datetime import json +import re +from collections import deque + @@ -311,6 +314,70 @@ def pull_all_images(): return {"message": run_command([f"{BIN_PATH}/pullAllContainers"])} + + +@app.post("/client/revert/{uuid}", dependencies=[Depends(verify_api_key)]) +def revert_changes(uuid: str): + return {"message": run_command([f"{BIN_PATH}/gitRevert", uuid ])} + + +@app.get("/client/logs/{uuid}", dependencies=[Depends(verify_api_key)]) +async def get_odoo_log_summary(uuid: str): + if not re.fullmatch(r"[0-9a-fA-F\-]+", uuid): + raise HTTPException(status_code=400, detail="Invalid UUID format. Only numbers, letters a-f, and '-' are allowed.") + + BASE_LOG_DIR = "/4server/data" + + # Build file paths as strings + project_dir = os.path.join(BASE_LOG_DIR, uuid) + odoo_log_file = os.path.join(project_dir, "logs", "odoo.log") + git_log_file = os.path.join(project_dir, "logs", "git.log") + + if not os.path.isfile(odoo_log_file): + raise HTTPException(status_code=404, detail="Odoo log file not found") + + # --- Helper variables and functions --- + IMPORTANT_PATTERNS = [ + re.compile(r"odoo\.addons\."), # Any Odoo addon log + re.compile(r"Job '.*' starting"), # Cron job start + re.compile(r"Job '.*' fully done"), # Cron job end + re.compile(r"ERROR"), # Errors + re.compile(r"WARNING"), # Warnings + re.compile(r"Traceback"), # Tracebacks + ] + + def is_important_line(line: str) -> bool: + return any(p.search(line) for p in IMPORTANT_PATTERNS) + + def read_last_lines(file_path: str, max_lines: int) -> list[str]: + """ + Read the last `max_lines` from the file efficiently. + """ + if not os.path.isfile(file_path): + return [] + last_lines = deque(maxlen=max_lines) + with open(file_path, "r", encoding="utf-8", errors="ignore") as f: + for line in f: + last_lines.append(line.strip()) + return list(last_lines) + + # --- Main logic --- + try: + # Last 500 lines from Odoo log + last_500_lines = read_last_lines(odoo_log_file, 500) + important_odoo_lines = [line for line in last_500_lines if is_important_line(line)] + + # Last 50 lines from git.log + last_50_git_lines = read_last_lines(git_log_file, 50) + + return { + "uuid": str(uuid), + "important_odoo_log_lines": important_odoo_lines, + "last_git_log_lines": last_50_git_lines, + } + except Exception as e: + raise HTTPException(status_code=500, detail=f"Error reading log files: {e}") + # ---------------------- Entry Point ---------------------- if __name__ == "__main__": print(VERSION) diff --git a/app/sbin/gitRevert b/app/sbin/gitRevert new file mode 100755 index 0000000..6f6d3e2 --- /dev/null +++ b/app/sbin/gitRevert @@ -0,0 +1,4 @@ +#!/bin/bash + +docker exec $1 /gitRollBack + diff --git a/app/vault/host_vars.img b/app/vault/host_vars.img index a276daf..b274c13 100644 Binary files a/app/vault/host_vars.img and b/app/vault/host_vars.img differ