172 lines
4.9 KiB
Python
172 lines
4.9 KiB
Python
# -*- mode: python; coding: utf-8 -*-
|
|
#
|
|
# Recuperation des addresses ip des serveurs
|
|
|
|
# Parfois, on prend un gaierror parce que hostname ne retourne rien, je sais
|
|
# pas d'où ça vient, mais c'est caca.
|
|
import socket
|
|
|
|
def pubipof(hostname):
|
|
return socket.gethostbyname(hostname + ".crans.org")
|
|
|
|
def admipof(hostname):
|
|
return socket.gethostbyname(hostname + ".adm.crans.org")
|
|
|
|
def wifiipof(hostname):
|
|
return socket.gethostbyname(hostname + ".wifi.crans.org")
|
|
|
|
def pubip():
|
|
return pubipof(hostname)
|
|
|
|
def admip():
|
|
return admipof(hostname)
|
|
|
|
def wifiip():
|
|
return wifiipof(hostname)
|
|
|
|
def ips_of_metadata(clients, vlan='adm'):
|
|
"""Renvoie la liste des IPs des machines de la liste ``clients``
|
|
#TODO: sur le vlan ``vlan``
|
|
sur le vlan adm
|
|
|
|
Renvoie les Ipv4 et Ipv6.
|
|
|
|
``clients`` est une liste de ClientMetadata, qui peut être obtenue via
|
|
metadata.query.by_groups (ou similaire)
|
|
"""
|
|
if vlan not in ['adm', 'adh']:
|
|
raise NotImplementedError('Seul adm et adh sont supportés')
|
|
out = []
|
|
for client in clients:
|
|
host = client.hostname
|
|
if vlan == 'adh':
|
|
host = host.split('.', 1)[0] + '.crans.org'
|
|
for res in socket.getaddrinfo(host, None, socket.AF_UNSPEC, socket.SOCK_STREAM):
|
|
# if res[0] == socket.AF_INET6:
|
|
# suffix = '/128'
|
|
# else:
|
|
# suffix = '/32'
|
|
out.append(res[4][0])
|
|
return out
|
|
|
|
ip_vlan = {
|
|
'sable' : {
|
|
'vlan-radin' : '10.42.0.1',
|
|
'vlan-accueil' : '10.51.0.1',
|
|
'vlan-ens' : '10.2.9.2',
|
|
'vlan-isolement':'10.52.0.1'
|
|
},
|
|
'dhcp' : {
|
|
'vlan-radin' : '10.42.0.34',
|
|
'vlan-accueil' : '10.51.0.34',
|
|
'vlan-ens' : '10.2.9.34',
|
|
'vlan-isolement':'10.52.0.34',
|
|
'vlan-federez': '10.53.0.34'
|
|
},
|
|
'nat64' : {
|
|
'vlan-radin' : '10.42.0.164',
|
|
},
|
|
'isc' : {
|
|
'vlan-radin' : '10.42.0.160',
|
|
'vlan-accueil' : '10.51.0.160',
|
|
'vlan-ens' : '10.2.9.160',
|
|
'vlan-isolement':'10.52.0.160',
|
|
'vlan-federez': '10.53.0.160'
|
|
},
|
|
'routeur' : {
|
|
'vlan-accueil' : '10.51.0.10',
|
|
'vlan-ens' : '10.2.9.10',
|
|
'vlan-isolement':'10.52.0.10'
|
|
},
|
|
'titanic' : {'vlan-ens' : '10.2.9.1' },
|
|
'odlyd' : {'vlan-ens' : '10.2.9.4' },
|
|
'pea' : {'vlan-federez' : '10.53.0.3' },
|
|
'eap' : {'vlan-federez' : '10.53.0.11' },
|
|
}
|
|
|
|
def radinip():
|
|
if has("vlan-radin"):
|
|
return ip_vlan[hostname]["vlan-radin"]
|
|
else:
|
|
raise NotImplementedError, "Ce serveur n'a rien a faire sur le VLAN radin"
|
|
|
|
def accueilip():
|
|
if has("vlan-accueil"):
|
|
return ip_vlan[hostname]["vlan-accueil"]
|
|
else:
|
|
raise NotImplementedError, "Ce serveur n'a rien a faire sur le VLAN d'accueil"
|
|
|
|
def appt_ens_ip():
|
|
if has("vlan-ens"):
|
|
return ip_vlan[hostname]["vlan-ens"]
|
|
else:
|
|
raise NotImplementedError, "Ce serveur n'a rien a faire sur le VLAN des appartements de l'ENS"
|
|
|
|
def federezip():
|
|
if has("vlan-federez"):
|
|
return ip_vlan[hostname]["vlan-federez"]
|
|
else:
|
|
raise NotImplementedError, "Ce serveur n'a rien a faire sur le VLAN federez"
|
|
|
|
def isolementip():
|
|
if has("vlan-isolement"):
|
|
return ip_vlan[hostname]["vlan-isolement"]
|
|
else:
|
|
raise NotImplementedError, "Ce serveur n'a rien a faire sur le VLAN isolement"
|
|
|
|
def cidr_to_regex(cidr):
|
|
"""Get a ipv4 cidr string and return a regexp for it.
|
|
https://chris-lamb.co.uk/posts/matching-ips-regexes-concidrd-harmful
|
|
"""
|
|
ip, prefix = cidr.split('/')
|
|
|
|
base = 0
|
|
for val in map(int, ip.split('.')):
|
|
base = (base << 8) | val
|
|
|
|
shift = 32 - int(prefix)
|
|
start = base >> shift << shift
|
|
end = start | (1 << shift) - 1
|
|
|
|
def regex(lower, upper):
|
|
if lower == upper:
|
|
return str(lower)
|
|
|
|
from math import log10
|
|
exp = int(log10(upper - lower))
|
|
delta = 10 ** exp
|
|
|
|
if lower == 0 and upper == 255:
|
|
return "\d+"
|
|
|
|
if delta == 1:
|
|
val = ""
|
|
for a, b in zip(str(lower), str(upper)):
|
|
if a == b:
|
|
val += str(a)
|
|
elif (a, b) == ("0", "9"):
|
|
val += '\d'
|
|
elif int(b) - int(a) == 1:
|
|
val += '[%s%s]' % (a, b)
|
|
else:
|
|
val += '[%s-%s]' % (a, b)
|
|
return val
|
|
|
|
def gen_classes():
|
|
floor_ = lambda x: int(round(x / delta, 0) * delta)
|
|
|
|
xs = range(floor_(upper) - delta, floor_(lower), -delta)
|
|
for x in map(str, xs):
|
|
yield '%s%s' % (x[:-exp], r'\d' * exp)
|
|
|
|
yield regex(lower, floor_(lower) + (delta - 1))
|
|
yield regex(floor_(upper), upper)
|
|
|
|
return '|'.join(gen_classes())
|
|
|
|
def get_parts():
|
|
for x in range(24, -1, -8):
|
|
yield regex(start >> x & 255, end >> x & 255)
|
|
|
|
return '^%s$' % r'\.'.join(get_parts())
|
|
|