-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrspamd-influxdb.py
130 lines (108 loc) · 6.43 KB
/
rspamd-influxdb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python
import argparse
import json
import urllib.request
parser = argparse.ArgumentParser(description="rspamd web interface statistic fetcher for InfluxDB usage")
parser.add_argument("--url", action="store", help="URL to rspamd web interface installation")
parser.add_argument("--password", action="store", help="Password for API authentication (same as for graphical login)")
parser.add_argument("--config", action="store", help="Path to the configuration file for the application to use")
args = parser.parse_args()
# Perform some stupid basic validation on the arguments
if (args.url is None and args.password is None) and args.config is None:
parser.error("Please provide --url and --password arguments or the path to a configuration file using --config")
if (args.url is None and args.password is not None) or (args.url is not None and args.password is None):
parser.error("Please use --url with the --password argument and way round. You may provide the path to a "
"configuration file by only using the --config argument.")
if args.url is not None and args.password is not None and args.config is not None:
parser.error("Please provide whether --url and --password arguments *or* --config argument.")
if args.config is not None and (args.url is not None or args.password is not None):
parser.error("Please provide whether --url and --password arguments *or* --config argument.")
# Basic variable initialization
url = None
password = None
# Read variables from file if necessary
if args.config is not None:
data = None
try:
fh = open(args.config, "r")
data = json.load(fh)
except IOError as e:
parser.error("Could not read JSON config from file. Received IOError: " + str(e))
if data is not None and ("url" not in data or "password" not in data):
parser.error("Could not read URL and password from JSON configuration. Please see documentation for correct "
"configuration file formatting.")
elif data is None:
parser.error("Something went wrong during parsing of JSON configuration file. Please check your configuration!")
else:
url = data['url']
password = data['password']
else:
# Read variable from args
url = args.url
password = args.password
# Make sure we got the trailing slash at the URL
if str.endswith(url, "/"):
fetch_url = url + "stat?password=" + urllib.parse.quote_plus(password)
else:
fetch_url = url + "/stat?password=" + urllib.parse.quote_plus(password)
try:
resp = urllib.request.urlopen(fetch_url)
except Exception:
print("Could not send GET request to given URL. Check url parameter!")
exit(1)
# Authorization failed
if resp.code == 403:
print("Authorization with rspamd web interface failed. Check password parameter!")
exit(1)
elif resp.code == 404:
print("HTTP server returned HTTP status code 404. Check url parameter!")
exit(1)
elif resp.code == 200:
# Successful call
json = json.loads(resp.read().decode('utf-8'))
action_reject = str(json["actions"]["reject"]) + "i"
action_soft_reject = str(json["actions"]["soft reject"]) + "i"
action_rewrite = str(json["actions"]["rewrite subject"]) + "i"
action_add_header = str(json["actions"]["add header"]) + "i"
action_greylist = str(json["actions"]["greylist"]) + "i"
action_no_action = str(json["actions"]["no action"]) + "i"
# Build InfluxDB Line protocol compatible output
print(
"rspamd_actions reject={0},soft_reject={1},rewrite_subject={2},add_header={3},greylist={4},no_action={5}".format(
action_reject, action_soft_reject, action_rewrite, action_add_header, action_greylist, action_no_action))
stat_scanned = str(json["scanned"]) + "i"
stat_learned = str(json["learned"]) + "i"
stat_spam_count = str(json["spam_count"]) + "i"
stat_ham_count = str(json["ham_count"]) + "i"
stat_connections = str(json["connections"]) + "i"
stat_control_connections = str(json["control_connections"]) + "i"
stat_pools_allocated = str(json["pools_allocated"]) + "i"
stat_pools_freed = str(json["pools_freed"]) + "i"
stat_bytes_allocated = str(json["bytes_allocated"]) + "i"
stat_chunks_allocated = str(json["chunks_allocated"]) + "i"
stat_chunks_freed = str(json["chunks_freed"]) + "i"
stat_chunks_oversized = str(json["chunks_oversized"]) + "i"
stat_fragmented = str(json["fragmented"]) + "i"
stat_total_learns = str(json["total_learns"]) + "i"
stat_fuzzy_rspamd = str(json["fuzzy_hashes"]["rspamd.com"]) + "i"
print("rspamd_stats scanned={0},learned={1},spam_count={2},ham_count={3},connections={4},control_connections={5},"
"pools_allocated={6},pools_freed={7},bytes_allocated={8},chunks_allocated={9},chunks_freed={10},"
"chunks_oversized={11},fragmented={12},total_learns={13},fuzzy={14}".format(stat_scanned, stat_learned,
stat_spam_count,
stat_ham_count,
stat_connections,
stat_control_connections,
stat_pools_allocated,
stat_pools_freed,
stat_bytes_allocated,
stat_chunks_allocated,
stat_chunks_freed,
stat_chunks_oversized,
stat_fragmented,
stat_total_learns,
stat_fuzzy_rspamd))
exit(0)
else:
print("Web request returned unhandled HTTP status code " + str(resp.code) + ". Please open an issue at GitHub "
"with further details.")
exit(1)