mirror of
https://github.com/centreon/centreon-plugins.git
synced 2025-08-19 08:38:26 +02:00
157 lines
5.5 KiB
Python
157 lines
5.5 KiB
Python
import subprocess
|
|
import time
|
|
import os
|
|
from robot.api.deco import keyword
|
|
import re
|
|
|
|
connector = None
|
|
|
|
class ConnectorLibrary:
|
|
def __init__(self):
|
|
self.process = None
|
|
|
|
def ctn_start_connector(self, command=["/usr/lib64/centreon-connector/centreon_connector_perl", "--log-file=/tmp/connector.log", "--debug"]):
|
|
if self.process is None or self.process.poll() is not None:
|
|
self.process = subprocess.Popen(
|
|
command,
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE, # Capture stdout!
|
|
text=True
|
|
)
|
|
print("Connector started")
|
|
|
|
def ctn_send_to_connector(self, idf: int, command: str, timeout: int, command_log="/tmp/connector.commands.log"):
|
|
now = int(time.time())
|
|
|
|
# Log to console
|
|
print(f"[Connector] Sending command (id={idf}, timeout={timeout}): {command}")
|
|
|
|
# Log to file
|
|
try:
|
|
with open(command_log, "a") as logf:
|
|
logf.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} id={idf} timeout={timeout} command={command}\n")
|
|
except Exception as e:
|
|
print(f"[Connector] Could not write to command log file: {e}")
|
|
|
|
buf = bytearray()
|
|
buf.extend(b"2\0")
|
|
buf.extend(f"{idf}\0".encode('utf-8'))
|
|
buf.extend(f"{timeout}\0".encode('utf-8'))
|
|
buf.extend(f"{now}\0".encode('utf-8'))
|
|
buf.extend(f"{command}\0\0\0\0".encode('utf-8'))
|
|
|
|
if self.process and self.process.stdin:
|
|
self.process.stdin.write(buf.decode('utf-8'))
|
|
self.process.stdin.flush()
|
|
else:
|
|
raise RuntimeError("Connector is not running.")
|
|
|
|
def ctn_write_next_output_to_file(self, output_file="/tmp/connector.output"):
|
|
"""
|
|
Reads the next line from the connector's stdout and appends it to output_file.
|
|
"""
|
|
if self.process and self.process.stdout:
|
|
line = self.process.stdout.readline()
|
|
if line:
|
|
with open(output_file, "a") as f:
|
|
f.write(line)
|
|
return line
|
|
return None
|
|
|
|
def ctn_kill_connector(self):
|
|
if self.process:
|
|
self.process.terminate()
|
|
self.process = None
|
|
print("Connector stopped")
|
|
|
|
def ctn_wait_for_output_file(output_file="/tmp/connector.output", timeout=10, poll_interval=0.2):
|
|
end_time = time.time() + timeout
|
|
while time.time() < end_time:
|
|
if os.path.exists(output_file):
|
|
return True
|
|
time.sleep(poll_interval)
|
|
raise FileNotFoundError(f"Output file {output_file} not found after {timeout} seconds")
|
|
|
|
def ctn_start_connector():
|
|
global connector
|
|
connector = ConnectorLibrary()
|
|
connector.ctn_start_connector()
|
|
return connector
|
|
|
|
def ctn_kill_connector():
|
|
global connector
|
|
if connector:
|
|
connector.ctn_kill_connector()
|
|
connector = None
|
|
else:
|
|
print("No connector to stop.")
|
|
|
|
def ctn_send_to_connector(idf: int, command: str, timeout: int = 5, output_file=None, command_log="/tmp/connector.commands.log"):
|
|
global connector
|
|
if connector:
|
|
connector.ctn_send_to_connector(idf, command, timeout, command_log)
|
|
# Capture the output line after sending command
|
|
output_file = output_file or f"/tmp/connector.output.{idf}"
|
|
line = connector.ctn_write_next_output_to_file(output_file)
|
|
# Copy per-test file to common output
|
|
if output_file != "/tmp/connector.output":
|
|
import shutil
|
|
shutil.copyfile(output_file, "/tmp/connector.output")
|
|
return line # Return the actual line written!
|
|
else:
|
|
raise RuntimeError("Connector is not running.")
|
|
|
|
def ctn_clean_connector_output(line):
|
|
if not isinstance(line, str):
|
|
line = str(line)
|
|
line = line.strip()
|
|
print(f"CLEAN DEBUG RAW: {repr(line)}") # This will show hidden chars
|
|
idx = line.find("OK:")
|
|
if idx != -1:
|
|
cleaned = line[idx:]
|
|
else:
|
|
# Fallback to regex if 'OK:' not found
|
|
cleaned = re.sub(r"^[^\w]*", "", line)
|
|
print(f"CLEANED: {repr(cleaned)}")
|
|
return cleaned
|
|
|
|
@keyword
|
|
def ctn_extract_multiline_result_from_log(tc, log_path="/tmp/connector.log", output_path=None, timeout=10):
|
|
"""
|
|
Extracts multi-line result for check ID from log, waits up to `timeout` seconds.
|
|
"""
|
|
import re
|
|
deadline = time.time() + timeout
|
|
result_lines = []
|
|
|
|
while time.time() < deadline:
|
|
with open(log_path, 'r') as f:
|
|
lines = f.readlines()
|
|
|
|
result_lines.clear()
|
|
in_result = False
|
|
|
|
for line in lines:
|
|
if not in_result:
|
|
m = re.search(r'reporting check result #(\d+) check:' + str(tc) + ' .*output:(.*)', line)
|
|
if m:
|
|
result_lines.append(m.group(2).strip())
|
|
in_result = True
|
|
else:
|
|
if line.strip().startswith("error:") or re.match(r"^\d+ \[20.*", line):
|
|
break
|
|
result_lines.append(line.strip())
|
|
|
|
if result_lines:
|
|
output_path = output_path or f"/tmp/connector.output.{tc}"
|
|
with open(output_path, 'w') as out:
|
|
out.write('\n'.join(result_lines))
|
|
if output_path != "/tmp/connector.output":
|
|
import shutil
|
|
shutil.copyfile(output_path, "/tmp/connector.output")
|
|
return '\n'.join(result_lines)
|
|
|
|
time.sleep(0.2) # wait before retry
|
|
|
|
raise Exception(f"No result found for id {tc} in log {log_path} after {timeout}s")
|