ntopng/python/examples/pdf/interface.py
Alfredo Cardigliano ada418ec2f Update README
2023-01-25 12:05:01 +01:00

279 lines
8 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Report creation script for the ntopng Python API
"""
import os
import sys
import time
import getopt
import pandas as pd
from fpdf import FPDF
import plotly.figure_factory as ff
import plotly.graph_objects as go
sys.path.insert(0, '../')
from ntopng.ntopng import Ntopng
### NTOPNG API SETUP
username = "admin"
password = "password"
ntopng_url = "http://localhost:4000"
iface_id = 2
auth_token = None
enable_debug = False
host_ip = "127.0.0.1"
actual_ts = int(time.time())
yesterday = (actual_ts - 86400)
##################################
######### DATA COLLECTOR #########
##################################
try:
my_ntopng = Ntopng(username, password, auth_token, ntopng_url)
if(enable_debug):
my_ntopng.enable_debug()
except ValueError as e:
print(e)
os._exit(-1)
try:
my_interface = my_ntopng.get_interface(iface_id)
my_historical = my_ntopng.get_historical_interface(iface_id)
except ValueError as e:
print(e)
os._exit(-1)
def get_alerts_severity():
"""
Return a dataframe with alerts and severity
"""
alert_count_severity = my_historical.get_alerts_stats(yesterday, actual_ts)
alert_severity_df = pd.DataFrame(alert_count_severity[0]["value"])
alert_severity_df.drop(["key", "title"], axis= 1, inplace=True)
return alert_severity_df
def get_top_client_server():
"""
Return a dataframe with top clients and servers seen on the interface specified in the above script init data
"""
top_client_server = my_historical.get_flow_alerts_stats(yesterday, actual_ts)
top_client_server_df = pd.DataFrame(top_client_server[0]["value"])
top_client_server_df.drop(["key", "value"], axis= 1, inplace=True)
return top_client_server_df
def get_host_info(ip):
"""
Return a dataframe with alerts and severity
:param ip: ip of the desired host to get data of
"""
my_host = my_interface.get_host(ip)
return my_host
def get_upload_download():
"""
Return a list where => data[0] = uploaded MB, data[1] = downloaded MB for the interface specified in the above script init data
"""
up_down = my_historical.get_interface_timeseries("iface:traffic_rxtx", yesterday, actual_ts)
data = [(up_down["bytes_sent"].sum()/1000000), (up_down["bytes_rcvd"].sum()/1000000)]
return data
def get_interface_data():
"""
Return a dict with info about the interface specified in the above script init data
"""
host_data = my_interface.get_data()
host_info = {"flow_count": host_data["num_flows"], "local_hosts": host_data["num_local_hosts"], "hosts_count": host_data["num_hosts"], "local_hosts_anomalies": host_data["num_local_hosts_anomalies"], "alerted_flows": host_data["alerted_flows"], "num_flows": host_data["num_flows"],
"flows_warning": host_data["alerted_flows_warning"], "flows_error": host_data["alerted_flows_error"]}
return host_info
def get_interfaces():
"""
Return a df with a list of all the interfaces
"""
interfaces = my_ntopng.get_interfaces_list()
interfaces_df = pd.DataFrame(interfaces)
interfaces_df.drop("name", axis=1, inplace=True)
return interfaces_df
def get_interfaces_count():
"""
Return number of interfaces
"""
interfaces = my_ntopng.get_interfaces_list()
return len(interfaces)
##################################
############# UTILS ##############
##################################
def delete_file(fname):
"""
Deletes the table png from the current path
:param fname: name of png to delete
"""
current_dir = os.getcwd()
path = current_dir+"/"+fname
try:
os.path.exists(path)
os.remove(path)
except Exception as e:
print(f"FILE: {path} DOES NOT EXIST...")
os._exit(-1)
def df_to_table_png(df, fname):
"""
Return creates a png of the df specified with name
:param df: dataframe to save to png
:param fname: name of the file to save
"""
fig = ff.create_table(df, colorscale=[[0, "#f3a114"], [.5, "#d9d9d9"], [1, "#ffffff"]])
fig.update_layout(autosize=False, width=1100, height=350)
fig.write_image(str(fname), scale=2)
def plot_up_down():
"""
Plots a png of the timeseries
"""
up_down = my_historical.get_interface_timeseries("iface:traffic_rxtx", yesterday, actual_ts)
up_down.reset_index(inplace=True)
up_down['ts'] = up_down['index'].apply(lambda x: x.left)
up_down['ts'] = pd.to_datetime(up_down['ts'], unit='s')
layout = dict(plot_bgcolor='rgba(255,255,255, 0.3)')
fig = go.Figure(layout=layout)
fig.add_trace(go.Scatter(x=up_down["ts"], y=up_down["bytes_rcvd"],
mode='lines',
name='Downloaded bytes',
line_color='#f3a114'))
fig.add_trace(go.Scatter(x=up_down["ts"], y=up_down["bytes_sent"],
mode='lines',
name='Uploaded bytes',
line_color='#000000'))
#fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='black')
#fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='black')
fig.write_image("series.png", width=1280, height=720)
##################################
######## DATA COLLECTION #########
##################################
created_files = []
interfaces_count = get_interfaces_count()
data_sent_rcvd = get_upload_download()
interface_data = get_interface_data()
#interfaces table
#interfaces_df = get_interfaces()
#interfaces_df_fname = "interfaces_table.png"
#created_files.append(interfaces_df_fname)
#df_to_table_png(interfaces_df, interfaces_df_fname)
#alerts table
alerts_df = get_alerts_severity()
alerts_df.columns = ["Alert Type", "Score", "Alert occurrence %"]
alerts_df_fname = "alerts_table.png"
created_files.append(alerts_df_fname)
df_to_table_png(alerts_df, alerts_df_fname)
#client/server table
hosts_df = get_top_client_server()
hosts_df.columns = ["Host occurrence %", "Vlan", "IP", "Host Name"]
hosts_df = hosts_df[["Host Name", "IP", "Host occurrence %", "Vlan"]]
hosts_df
hosts_df_fname = "hosts_table.png"
created_files.append(hosts_df_fname)
df_to_table_png(hosts_df, hosts_df_fname)
## UPLOADED/DOWNLOADED IN MB
uploaded = data_sent_rcvd[0]
downloaded = data_sent_rcvd[1]
## INFO FOR SPECIFIED IFID
flows = interface_data["num_flows"]
host_num = interface_data["hosts_count"]
local_hosts_num = interface_data["local_hosts"]
flows_errors = interface_data["flows_error"]
flows_warnings = interface_data["flows_warning"]
##################################
########## PDF CREATION ##########
##################################
MARGIN = 10
pw = 25 - 2*MARGIN
ch = 50
pdf = FPDF()
pdf.add_page()
## LOGO
pdf.image("img/ntop.png", x=140, y=8, w=68.2, h=17.8)
## HOST PC SPECS AND STATS ##
pdf.set_font("Helvetica", "B", 14)
pdf.set_text_color(r= 0, g= 0, b = 0)
pdf.ln(9)
pdf.cell(w=0, h=10, txt="HOST INFO", ln=1)
pdf.set_font("Helvetica", "", 11)
pdf.cell(w=0, h=5, txt=f"Host: {host_ip}")
pdf.ln(5)
pdf.cell(w=0, h=5, txt=f"Timestamp: {time.strftime('%d-%m-%Y %H:%M:%S', time.localtime(actual_ts))}")
pdf.ln(5)
pdf.cell(w=0, h=5, txt=f"# Interfaces: {interfaces_count}")
pdf.ln(7)
## 24hr stats ##
pdf.set_font("Helvetica", "B", 14)
pdf.cell(w=0, h=10, txt="24h STATS")
pdf.ln(5)
pdf.set_font("Helvetica", "", 11)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"Flows: {flows}")
pdf.ln(5)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"Hosts count: {host_num}")
pdf.ln(5)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"Local hosts count: {local_hosts_num}")
pdf.ln(5)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"UP/DOWN MB: {uploaded:.3f}/{downloaded:.3f}")
pdf.ln(5)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"Flows errors: {flows_errors}")
pdf.ln(5)
pdf.cell(w=(pw/2), h=(ch/4), txt=f"Flows warnings: {flows_warnings}")
pdf.ln(5)
# Alerts
pdf.image("alerts_table.png", x=10, y=75, w=190, h=65)
## Hosts
pdf.image("hosts_table.png", x=10, y=135, w=190, h=65)
# Series plot
plot_up_down()
pdf.image("series.png", x=10, y=210, w=190, h=85)
created_files.append("report.pdf")
created_files.append("series.png")
pdf.output(f"./report.pdf", "F")
for file in created_files:
delete_file(file)