Compare commits
2 Commits
2683cdb882
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48c5183c12 | ||
|
|
edc4fc44c5 |
@@ -18,6 +18,10 @@ from modules.device.routes import (
|
|||||||
device_bp
|
device_bp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from modules.monitor_config.routes import (
|
||||||
|
monitor_config_bp
|
||||||
|
)
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
# Register Global Exception Handlers
|
# Register Global Exception Handlers
|
||||||
@@ -39,6 +43,11 @@ app.register_blueprint(
|
|||||||
url_prefix="/api/devices"
|
url_prefix="/api/devices"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
app.register_blueprint(
|
||||||
|
monitor_config_bp,
|
||||||
|
url_prefix="/api/devices"
|
||||||
|
)
|
||||||
|
|
||||||
# @app.route("/")
|
# @app.route("/")
|
||||||
# def home():
|
# def home():
|
||||||
# return {
|
# return {
|
||||||
|
|||||||
57
backend/modules/alert/repository.py
Normal file
57
backend/modules/alert/repository.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# pyrefly: ignore [missing-import]
|
||||||
|
from config.database import get_connection, release_connection
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# REPOSITORY LAYER: Tương tác trực tiếp với bảng alert_config trong PostgreSQL
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
def insert_default_alert_config_db(device_id):
|
||||||
|
"""
|
||||||
|
Tạo cấu hình cảnh báo mặc định cho thiết bị mới.
|
||||||
|
|
||||||
|
Tham số mặc định trong DB/Đặc tả:
|
||||||
|
- is_enabled = True
|
||||||
|
- fail_threshold = 3 (lỗi 3 lần liên tiếp thì alert)
|
||||||
|
- cooldown_minutes = 30 (khoảng thời gian tối thiểu giữa 2 cảnh báo tránh spam)
|
||||||
|
- notify_web = True (thông báo hiển thị trên giao diện)
|
||||||
|
- notify_email = False (mặc định chưa bật gửi email)
|
||||||
|
"""
|
||||||
|
conn = get_connection()
|
||||||
|
cur = None
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO alert_config (device_id, is_enabled, fail_threshold, cooldown_minutes, notify_web, notify_email)
|
||||||
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
|
RETURNING id, device_id, is_enabled, fail_threshold, cooldown_minutes, notify_web, notify_email, created, modified
|
||||||
|
""", (
|
||||||
|
device_id,
|
||||||
|
True, # is_enabled
|
||||||
|
3, # fail_threshold
|
||||||
|
30, # cooldown_minutes
|
||||||
|
True, # notify_web
|
||||||
|
False # notify_email
|
||||||
|
))
|
||||||
|
row = cur.fetchone()
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
if row:
|
||||||
|
return {
|
||||||
|
"id": str(row[0]),
|
||||||
|
"device_id": str(row[1]),
|
||||||
|
"is_enabled": row[2],
|
||||||
|
"fail_threshold": row[3],
|
||||||
|
"cooldown_minutes": row[4],
|
||||||
|
"notify_web": row[5],
|
||||||
|
"notify_email": row[6],
|
||||||
|
"created": row[7].isoformat() if row[7] else None,
|
||||||
|
"modified": row[8].isoformat() if row[8] else None
|
||||||
|
}
|
||||||
|
return None
|
||||||
|
except Exception:
|
||||||
|
conn.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if cur:
|
||||||
|
cur.close()
|
||||||
|
release_connection(conn)
|
||||||
12
backend/modules/alert/service.py
Normal file
12
backend/modules/alert/service.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# pyrefly: ignore [missing-import]
|
||||||
|
from modules.alert.repository import insert_default_alert_config_db
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# SERVICE LAYER: Xử lý nghiệp vụ cho Module Alert
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
def create_default_alert_config_service(device_id):
|
||||||
|
"""
|
||||||
|
Tạo cấu hình cảnh báo mặc định cho thiết bị mới.
|
||||||
|
"""
|
||||||
|
return insert_default_alert_config_db(device_id)
|
||||||
@@ -134,8 +134,7 @@ def find_device_by_ip(ip_address):
|
|||||||
|
|
||||||
def insert_device(data):
|
def insert_device(data):
|
||||||
"""
|
"""
|
||||||
Tạo mới một thiết bị và cấu hình mặc định (MonitorConfig & AlertConfig)
|
Tạo mới một thiết bị mạng (chỉ ghi nhận vào bảng device).
|
||||||
trong cùng một database transaction.
|
|
||||||
"""
|
"""
|
||||||
conn = get_connection()
|
conn = get_connection()
|
||||||
cur = None
|
cur = None
|
||||||
@@ -163,34 +162,7 @@ def insert_device(data):
|
|||||||
device_row = cur.fetchone()
|
device_row = cur.fetchone()
|
||||||
device_id = device_row[0]
|
device_id = device_row[0]
|
||||||
|
|
||||||
# 2. Thêm cấu hình giám sát mặc định (MonitorConfig) cho thiết bị vừa tạo
|
# 2. Lấy lại thiết bị kèm thông tin DeviceType đã JOIN để trả về đầy đủ dữ liệu
|
||||||
# enable_ping mặc định bật True để thực hiện Ping giám sát
|
|
||||||
cur.execute("""
|
|
||||||
INSERT INTO monitor_config (device_id, enable_ping, ping_count, ping_timeout, ping_interval, enable_snmp)
|
|
||||||
VALUES (%s, %s, %s, %s, %s, %s)
|
|
||||||
""", (
|
|
||||||
device_id,
|
|
||||||
True, # enable_ping
|
|
||||||
3, # ping_count
|
|
||||||
5, # ping_timeout (giây)
|
|
||||||
60, # ping_interval (giây)
|
|
||||||
False # enable_snmp
|
|
||||||
))
|
|
||||||
|
|
||||||
# 3. Thêm cấu hình cảnh báo mặc định (AlertConfig) cho thiết bị vừa tạo
|
|
||||||
cur.execute("""
|
|
||||||
INSERT INTO alert_config (device_id, is_enabled, fail_threshold, cooldown_minutes, notify_web, notify_email)
|
|
||||||
VALUES (%s, %s, %s, %s, %s, %s)
|
|
||||||
""", (
|
|
||||||
device_id,
|
|
||||||
True, # is_enabled
|
|
||||||
3, # fail_threshold (số lần fail liên tiếp trước khi alert)
|
|
||||||
30, # cooldown_minutes (thời gian tránh spam alert)
|
|
||||||
True, # notify_web (hiển thị thông báo trên web)
|
|
||||||
False # notify_email (mặc định tắt gửi email)
|
|
||||||
))
|
|
||||||
|
|
||||||
# 4. Lấy lại thiết bị kèm thông tin DeviceType đã JOIN để trả về đầy đủ dữ liệu
|
|
||||||
cur.execute("""
|
cur.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
d.id, d.device_type_id, d.name, d.description, d.ip_address, d.port,
|
d.id, d.device_type_id, d.name, d.description, d.ip_address, d.port,
|
||||||
@@ -202,7 +174,7 @@ def insert_device(data):
|
|||||||
""", (device_id,))
|
""", (device_id,))
|
||||||
full_row = cur.fetchone()
|
full_row = cur.fetchone()
|
||||||
|
|
||||||
# Commit toàn bộ transaction
|
# Commit transaction
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
return _row_to_dict(full_row)
|
return _row_to_dict(full_row)
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ from scheduler.scheduler import (
|
|||||||
remove_device_monitoring_job,
|
remove_device_monitoring_job,
|
||||||
reschedule_device_monitoring_job
|
reschedule_device_monitoring_job
|
||||||
)
|
)
|
||||||
|
from modules.monitor_config.service import create_default_monitor_config_service
|
||||||
|
from modules.alert.service import create_default_alert_config_service
|
||||||
|
|
||||||
|
|
||||||
def get_devices_service():
|
def get_devices_service():
|
||||||
@@ -62,12 +64,17 @@ def create_device_service(data):
|
|||||||
if existing_ip:
|
if existing_ip:
|
||||||
raise DeviceIPAlreadyExistsException(data["ip_address"])
|
raise DeviceIPAlreadyExistsException(data["ip_address"])
|
||||||
|
|
||||||
# 4. Insert DB
|
# 4. Insert DB (Chỉ lưu vào bảng device)
|
||||||
new_device = insert_device(data)
|
new_device = insert_device(data)
|
||||||
|
|
||||||
# 5. Kích hoạt Job giám sát trên Background Scheduler
|
# 5. Tạo cấu hình giám sát mặc định (thuộc module monitor_config)
|
||||||
# Truyền kèm thông tin cấu hình mặc định (enable_ping=True, v.v...)
|
monitor_config = create_default_monitor_config_service(new_device["id"])
|
||||||
add_device_monitoring_job(new_device["id"], None)
|
|
||||||
|
# 6. Tạo cấu hình cảnh báo mặc định (thuộc module alert)
|
||||||
|
create_default_alert_config_service(new_device["id"])
|
||||||
|
|
||||||
|
# 7. Kích hoạt Job giám sát trên Background Scheduler
|
||||||
|
add_device_monitoring_job(new_device["id"], monitor_config)
|
||||||
|
|
||||||
return new_device
|
return new_device
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,47 @@ def _row_to_dict(row):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# INSERT DEFAULT: Tạo cấu hình giám sát mặc định cho thiết bị mới
|
||||||
|
# ============================================
|
||||||
|
def insert_default_monitor_config_db(device_id, cursor=None):
|
||||||
|
"""
|
||||||
|
Thêm cấu hình giám sát mặc định cho thiết bị mới.
|
||||||
|
Nếu có cursor được truyền vào (từ transaction của device), dùng chung cursor đó.
|
||||||
|
Nếu không, tự tạo connection riêng.
|
||||||
|
"""
|
||||||
|
sql = """
|
||||||
|
INSERT INTO monitor_config (device_id, enable_ping, ping_count, ping_timeout, ping_interval, enable_snmp)
|
||||||
|
VALUES (%s, %s, %s, %s, %s, %s)
|
||||||
|
RETURNING id, device_id, enable_ping, ping_count, ping_timeout, ping_interval,
|
||||||
|
enable_snmp, snmp_version, snmp_community, snmp_port, snmp_interval,
|
||||||
|
snmp_timeout, snmp_custom_oids, created, modified
|
||||||
|
"""
|
||||||
|
# Mặc định bật Ping giám sát (enable_ping=True), ping_count=3, timeout=5s, interval=60s
|
||||||
|
params = (device_id, True, 3, 5, 60, False)
|
||||||
|
|
||||||
|
if cursor:
|
||||||
|
cursor.execute(sql, params)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
return _row_to_dict(row)
|
||||||
|
else:
|
||||||
|
conn = get_connection()
|
||||||
|
cur = None
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(sql, params)
|
||||||
|
row = cur.fetchone()
|
||||||
|
conn.commit()
|
||||||
|
return _row_to_dict(row)
|
||||||
|
except Exception:
|
||||||
|
conn.rollback()
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if cur:
|
||||||
|
cur.close()
|
||||||
|
release_connection(conn)
|
||||||
|
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# FIND BY DEVICE ID: Lấy cấu hình giám sát của một thiết bị
|
# FIND BY DEVICE ID: Lấy cấu hình giám sát của một thiết bị
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|||||||
27
backend/modules/monitor_config/routes.py
Normal file
27
backend/modules/monitor_config/routes.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# pyrefly: ignore [missing-import]
|
||||||
|
from flask import Blueprint
|
||||||
|
|
||||||
|
from modules.monitor_config.controller import (
|
||||||
|
get_monitor_config,
|
||||||
|
update_monitor_config,
|
||||||
|
test_connection
|
||||||
|
)
|
||||||
|
|
||||||
|
# Khởi tạo Blueprint cho Module Monitor Config
|
||||||
|
# Blueprint này sẽ được đăng ký dưới prefix /api/devices trong app.py
|
||||||
|
monitor_config_bp = Blueprint("monitor_config", __name__)
|
||||||
|
|
||||||
|
# Đăng ký các endpoints cấu hình giám sát thiết bị:
|
||||||
|
# Luồng đi:
|
||||||
|
# 1. Client gửi request tương ứng tới endpoint.
|
||||||
|
# 2. Flask định tuyến (routing) request dựa trên method và url path.
|
||||||
|
# 3. Chuyển tiếp request cho hàm xử lý tương ứng trong controller.py.
|
||||||
|
|
||||||
|
# GET /api/devices/<device_id>/monitor-config -> Lấy cấu hình giám sát
|
||||||
|
monitor_config_bp.route("/<device_id>/monitor-config", methods=["GET"])(get_monitor_config)
|
||||||
|
|
||||||
|
# PUT /api/devices/<device_id>/monitor-config -> Cập nhật cấu hình giám sát
|
||||||
|
monitor_config_bp.route("/<device_id>/monitor-config", methods=["PUT"])(update_monitor_config)
|
||||||
|
|
||||||
|
# POST /api/devices/<device_id>/monitor-config/test -> Kiểm tra kết nối (Ping/SNMP)
|
||||||
|
monitor_config_bp.route("/<device_id>/monitor-config/test", methods=["POST"])(test_connection)
|
||||||
@@ -22,13 +22,24 @@ import platform
|
|||||||
|
|
||||||
from modules.monitor_config.repository import (
|
from modules.monitor_config.repository import (
|
||||||
find_monitor_config_by_device_id,
|
find_monitor_config_by_device_id,
|
||||||
update_monitor_config_db
|
update_monitor_config_db,
|
||||||
|
insert_default_monitor_config_db
|
||||||
)
|
)
|
||||||
from modules.monitor_config.exceptions import MonitorConfigNotFoundException
|
from modules.monitor_config.exceptions import MonitorConfigNotFoundException
|
||||||
from modules.device.repository import find_device_by_id
|
from modules.device.repository import find_device_by_id
|
||||||
from modules.device.exceptions import DeviceNotFoundException
|
from modules.device.exceptions import DeviceNotFoundException
|
||||||
from scheduler.scheduler import reschedule_device_monitoring_job
|
from scheduler.scheduler import reschedule_device_monitoring_job
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# CREATE DEFAULT: Tạo cấu hình giám sát mặc định (Service Layer)
|
||||||
|
# ============================================
|
||||||
|
def create_default_monitor_config_service(device_id, cursor=None):
|
||||||
|
"""
|
||||||
|
Tạo cấu hình giám sát mặc định cho thiết bị mới.
|
||||||
|
"""
|
||||||
|
return insert_default_monitor_config_db(device_id, cursor)
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Dynamic Import: icmplib và pysnmp
|
# Dynamic Import: icmplib và pysnmp
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|||||||
Reference in New Issue
Block a user