forked from jda/FreeRADIUS-NAS-change-restarter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reloader.py
executable file
·124 lines (96 loc) · 2.85 KB
/
reloader.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
#!/usr/bin/python
# Safely reload FreeRADIUS after NAS table changes
# 10-2011 Jon Auer
#
try:
import json
except ImportError:
import simplejson as json
import pyrad.packet
import MySQLdb
import sys
import subprocess
import time
import random
markerpath = "/var/lib/reloader/marker"
def get_db_version(config):
conn = MySQLdb.connect(
config['host'],
config['username'],
config['password'],
config['database'])
curs = conn.cursor()
curs.execute("SELECT `id` from `nas_changes` order by `id` desc limit 1")
data = curs.fetchone()[0]
curs.close()
conn.close()
return int(data)
def get_local_version(markerpath):
try:
marker = open(markerpath)
except IOError:
marker = open(markerpath, 'w')
marker.write('0')
marker.close()
marker = open(markerpath)
local_ver = marker.read()
marker.close()
return int(local_ver)
def set_local_version(markerpath, ver):
marker = open(markerpath, 'w')
marker.write(str(ver))
marker.close()
def peers_alive(config):
from pyrad.client import Client
from pyrad.dictionary import Dictionary
radconfig = config['radius']
localconfig = config['local']
auth_OK = True
dictionary = Dictionary(localconfig['raddict'])
for server in radconfig['servers']:
srv = Client(server=server, secret=str(radconfig['secret']), dict=dictionary)
req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest,
User_Name=radconfig['username'],
NAS_Identifier="localhost")
req["User-Password"] = req.PwCrypt(radconfig['password'])
try:
reply = srv.SendPacket(req)
except pyrad.client.Timeout:
print "Could not contact:", server
auth_OK = False
if reply.code != 2:
print "Auth failed to", server
auth_OK = False
return auth_OK
def restart_radius(radpath):
status = subprocess.call([radpath, "restart"])
return status
# Get/make sure we have a config
if len(sys.argv) == 2:
# read json from file param
configFile = open(sys.argv[1], 'r')
else:
# try to read from /etc
try:
configFile = open('/etc/reloader.json', 'r')
except IOError:
print "No config provided as param and could not open /etc/reloader.json"
sys.exit(1)
config = json.loads(configFile.read())
configFile.close()
db_ver = get_db_version(config['database'])
local_ver = get_local_version(markerpath)
if db_ver > local_ver:
print "Reload needed"
if peers_alive(config):
print "Peers alive. Time for random sleep to reduce change of collision with other restart"
time.sleep(random.randrange(5,30,1))
if peers_alive(config):
print "Peers alive both times, restarting"
status = restart_radius(config['local']['radpath'])
if status==0:
set_local_version(markerpath, db_ver)
else:
print "Peers dead. Try later"
else:
print "No changes detected in mysql database - no reload needed"