193 lines
5.5 KiB
Python
Executable File
193 lines
5.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
PROCEDURE RUNNER
|
|
Exécute les procédures de send enregistrées:
|
|
- Affiche les étapes
|
|
- Guide l'opérateur
|
|
- Valide chaque étape
|
|
- Log les résultats
|
|
"""
|
|
|
|
import psycopg2
|
|
import json
|
|
from datetime import datetime
|
|
|
|
DB_CONFIG = {
|
|
'host': 'localhost',
|
|
'database': 'adx_system',
|
|
'user': 'admin',
|
|
'password': 'admin123'
|
|
}
|
|
|
|
def get_db():
|
|
return psycopg2.connect(**DB_CONFIG)
|
|
|
|
def list_procedures():
|
|
"""List all available procedures"""
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
|
|
print("=" * 70)
|
|
print("📋 AVAILABLE SENDING PROCEDURES")
|
|
print("=" * 70)
|
|
|
|
cur.execute("""
|
|
SELECT id, procedure_name, target_isp, target_country,
|
|
cloud_provider, cloud_region, status, created_by
|
|
FROM admin.sending_procedures
|
|
ORDER BY target_isp, procedure_name
|
|
""")
|
|
|
|
for row in cur.fetchall():
|
|
pid, name, isp, country, provider, region, status, author = row
|
|
status_icon = '✅' if status == 'active' else '⚠️'
|
|
print(f"\n{status_icon} [{pid}] {name}")
|
|
print(f" ISP: {isp} ({country}) | Cloud: {provider}/{region}")
|
|
print(f" Author: {author}")
|
|
|
|
conn.close()
|
|
|
|
def show_procedure(procedure_id):
|
|
"""Show detailed procedure"""
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT procedure_name, description, target_isp, target_country,
|
|
cloud_provider, cloud_region, server_count_min, os_type,
|
|
placeholders, validation_rules, procedure_steps,
|
|
max_volume_per_server, created_by
|
|
FROM admin.sending_procedures WHERE id = %s
|
|
""", (procedure_id,))
|
|
|
|
row = cur.fetchone()
|
|
if not row:
|
|
print(f"Procedure {procedure_id} not found")
|
|
return
|
|
|
|
name, desc, isp, country, provider, region, servers, os, \
|
|
placeholders, rules, steps, max_vol, author = row
|
|
|
|
# Parse JSON
|
|
placeholders = json.loads(placeholders) if isinstance(placeholders, str) else placeholders
|
|
rules = json.loads(rules) if isinstance(rules, str) else rules
|
|
steps = json.loads(steps) if isinstance(steps, str) else steps
|
|
|
|
print("=" * 70)
|
|
print(f"📋 {name}")
|
|
print("=" * 70)
|
|
print(f"\n📝 {desc}")
|
|
print(f"\n🎯 Target: {isp} ({country})")
|
|
print(f"☁️ Cloud: {provider} / {region}")
|
|
print(f"🖥️ Servers: {servers} minimum, OS: {os}")
|
|
print(f"📧 Max volume/server: {max_vol:,}")
|
|
|
|
# Placeholders
|
|
print("\n📦 PLACEHOLDERS:")
|
|
for ph, info in placeholders.items():
|
|
desc = info.get('description', info.get('type', ''))
|
|
print(f" {ph}: {desc}")
|
|
|
|
# Validation Rules
|
|
print("\n✅ VALIDATION RULES:")
|
|
for key, value in rules.items():
|
|
print(f" • {key}: {value}")
|
|
|
|
# Steps
|
|
print("\n📋 PROCEDURE STEPS:")
|
|
print("-" * 70)
|
|
|
|
for step in steps:
|
|
step_num = step.get('step', '?')
|
|
step_name = step.get('name', 'Unknown')
|
|
action = step.get('action', '')
|
|
validation = step.get('validation', '')
|
|
wait = step.get('wait_minutes', 0)
|
|
note = step.get('note', '')
|
|
on_fail = step.get('on_fail', '')
|
|
|
|
print(f"\n STEP {step_num}: {step_name}")
|
|
print(f" ➡️ Action: {action}")
|
|
|
|
if step.get('params'):
|
|
print(f" 📌 Params: {step['params']}")
|
|
if wait:
|
|
print(f" ⏱️ Wait: {wait} minutes")
|
|
if validation:
|
|
print(f" ✅ Validation: {validation}")
|
|
if on_fail:
|
|
print(f" ❌ On Fail: {on_fail}")
|
|
if note:
|
|
print(f" 📝 Note: {note}")
|
|
|
|
conn.close()
|
|
|
|
def get_isp_rules(isp):
|
|
"""Get validation rules for ISP"""
|
|
conn = get_db()
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT scl_max, scl_action, out_min, out_zero_action,
|
|
test_count_min, stability_tests, wait_after_scl_high_hours, notes
|
|
FROM admin.isp_validation_rules WHERE isp_name = %s
|
|
""", (isp,))
|
|
|
|
row = cur.fetchone()
|
|
conn.close()
|
|
|
|
if row:
|
|
return {
|
|
'scl_max': row[0],
|
|
'scl_action': row[1],
|
|
'out_min': row[2],
|
|
'out_zero_action': row[3],
|
|
'test_count_min': row[4],
|
|
'stability_tests': row[5],
|
|
'wait_hours': row[6],
|
|
'notes': row[7]
|
|
}
|
|
return None
|
|
|
|
def show_isp_rules(isp):
|
|
"""Show ISP validation rules"""
|
|
rules = get_isp_rules(isp)
|
|
|
|
if not rules:
|
|
print(f"No rules found for {isp}")
|
|
return
|
|
|
|
print(f"\n📋 VALIDATION RULES FOR {isp.upper()}")
|
|
print("=" * 50)
|
|
print(f" SCL Max: {rules['scl_max']}")
|
|
print(f" SCL Action: {rules['scl_action']}")
|
|
print(f" Out Min: {rules['out_min']}")
|
|
print(f" Out=0 Action: {rules['out_zero_action']}")
|
|
print(f" Test Count: {rules['test_count_min']}")
|
|
print(f" Stability Tests: {rules['stability_tests']}")
|
|
print(f" Wait after high SCL: {rules['wait_hours']}h")
|
|
print(f"\n 📝 Notes: {rules['notes']}")
|
|
|
|
def main():
|
|
import sys
|
|
|
|
if len(sys.argv) < 2:
|
|
list_procedures()
|
|
return
|
|
|
|
cmd = sys.argv[1]
|
|
|
|
if cmd == 'list':
|
|
list_procedures()
|
|
elif cmd == 'show':
|
|
proc_id = int(sys.argv[2]) if len(sys.argv) > 2 else 1
|
|
show_procedure(proc_id)
|
|
elif cmd == 'rules':
|
|
isp = sys.argv[2] if len(sys.argv) > 2 else 'videotron'
|
|
show_isp_rules(isp)
|
|
else:
|
|
print("Commands: list, show <id>, rules <isp>")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|