Notifier un serveur de son changement d'adresse IP
Il arrive parfois que nous avons un équipement qui change d'adresse IP, mais dont nous désirons connaître ce dernier sans avoir nécessairement accès au routeur, au DHCP ou à un autre service tier. Voici donc un script qui sert à notifier, dans une base de données, un changement au niveau de l'adresse IP. Je vous laisse deviner le contenu de la stored procedure utilisée... si vous comprenez le contenu de ce blogue, c'est que vous êtes sans doute en mesure de comprendre cette partie!
Le script ne fait rien de très compliqué, à part de s'assurer de s'exécuter la plupart du temps (et même en cas d'exception), il obtient son adresse IP, fait toujours une mise à jour la première fois et les mises à jour subséquentes n'auront lieu que lorsque l'adresse aura changée.Idéalement, ce script devrait être lancé automatiquement au démarrage du périphérique, en utilisant systemctl, par exemple.
updateip.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 | #!/usr/bin/env python
import struct
import socket
import fcntl
import getopt
import sys
import os
import time
CFG_DATABASE_IP = "192.168.10.4"
CFG_DATABASE_USER = "user"
CFG_DATABASE_PWD = "passwd"
CFG_DATABASE_NAME = "iplist"
CFG_DEFAULT_IP_VALIDATION = 15
def setargs(argv):
global s_dev
try:
opts, args = getopt.getopt(argv, "h:i:", [])
for opt, arg in opts:
if opt == '-h':
help_exit()
elif opt in "-i":
s_dev = arg
except getopt.GetoptError:
help_exit()
if s_dev is None:
help_exit()
def help_exit():
print(get_name() + ' -i <eth> [-h]')
sys.exit()
def get_name():
return os.path.basename(sys.argv[0])
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s_ip = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915,
struct.pack('256s', ifname[:15]))[20:24])
except IOError:
s_ip = None
return s_ip
def get_mac_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', ifname[:15]))
return ':'.join(['%02x' % ord(char) for char in info[18:24]]).upper()
def get_netmask(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s_mask = socket.inet_ntoa(fcntl.ioctl(s.fileno(), 35099,
struct.pack('256s', ifname))[20:24])
except IOError:
s_mask = None
return s_mask
def check_ip(h_eth, s_dev):
s_ip = get_ip_address(s_dev)
s_mac = get_mac_address(s_dev)
s_mask = get_netmask(s_dev)
# we do more validation if we are waiting for interface to become ready...
if s_ip is None or s_mac is None or s_mask is None:
time.sleep(30)
return True
if h_eth['ip'] != s_ip or h_eth['mac'] != s_mac or h_eth['mask'] != s_mask:
h_eth['ip'] = s_ip
h_eth['mac'] = s_mac
h_eth['mask'] = s_mask
conn = pg8000.connect(host=CFG_DATABASE_IP, user=CFG_DATABASE_USER,
password=CFG_DATABASE_PWD,
database=CFG_DATABASE_NAME, socket_timeout=5)
cursor = conn.cursor()
cursor.execute("SELECT FROM sp_update_ip(%s, %s, %s)",
[s_mac, s_ip, s_mask])
cursor.close()
conn.commit()
return False
if __name__ == '__main__':
s_dev = None
h_eth = dict(ip=None, mac=None, mask=None)
setargs(sys.argv[1:])
while True:
try:
if check_ip(h_eth, s_dev):
continue
except pg8000.InterfaceError as err:
print("Database error!")
except IOError as (errno, strerror):
print("I/O error({0}): {1}".format(errno, strerror))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error : ", sys.exc_info()[0])
# raise
time.sleep(60 * CFG_DEFAULT_IP_VALIDATION)
|