scripts/gestion/ridtools.py
Daniel STAN 7426578b0d gestion: retrait des shabang inutiles
Puisque les fichiers ne sont pas executables
2014-10-24 23:07:37 +02:00

162 lines
5.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
#
# RIDTOOLS.PY -- Gestion de la conversion rid <-> IP
#
# Copyright (C) 2010 Olivier Iffrig
# (c) 2010 Nicolas Dandrimont
# Authors: Olivier Iffrig <iffrig@crans.org>
# Nicolas Dandrimont <olasd@crans.org>
# Adapté par Pierre-Elliott Bécue pour cause de changement de schéma.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import netaddr
import itertools
import config
class Rid(object):
"""
Permet de décortiquer un rid et d'obtenir les IP correspondantes
Variables d'instance :
- rid : le rid
- type : type de rid (cf. config.rid et [1])
- reste : le "reste" du rid (permettant de calculer l'IP par exemple)
- ipv4_dispo : une IPv4 existe pour ce rid
- priv : cette machine ne doit pas être accessible de l'extérieur
[1] http://wiki.crans.org/CransTechnique/PlanAdressage#Machines
"""
def __init__(self, rid=None, ipv4=None):
self.rid = None
self.reste = False
self.type = None
self.ipv4_dispo = False
self.priv = False
if rid is not None:
self.__parse(rid)
elif ipv4 is not None:
self.__from_ipv4(ipv4)
else:
raise ValueError("Un des champs rid et ipv4 doit être défini")
def __parse(self, rid):
"""Peuple les champs de l'instance par rapport au rid"""
self.rid = rid
self.type = find_rid_plage(int(rid))
if self.type == 'Inconnu':
raise ValueError("rid inconnu : %d" % rid)
self.ipv4_dispo = (rid & (1 << 15)) == 0 and self.type != 'special' or self.rid in config.rid_machines_speciales
self.priv = (rid & (1 << 14)) != 0
if self.type == 'personnel-ens':
self.reste = rid & 0xff
else:
self.reste = rid & 0x7ff
def __from_ipv4(self, ip):
"""Peuple les champs à partir de l'ipv4 donnée"""
if not isinstance(ip, netaddr.IPAddress):
ip = netaddr.IPAddress(ip)
try:
ip.ipv4()
except netaddr.AddrConversionError:
raise ValueError("Ceci n'est pas une IPv4... %s" % ip)
self.ipv4_dispo = True
self.priv = ip.is_private()
for tp in config.NETs_primaires.keys():
for net in config.NETs_primaires[tp]:
if ip in netaddr.IPNetwork(net):
self.type = tp
break
if self.type:
break
else:
for rid, ip_speciale in config.rid_machines_speciales.items():
if ip == netaddr.IPAddress(ip_speciale):
self.rid = rid
self.type = "special"
break
else:
raise ValueError("%s dans aucun des réseaux gérés par le Cr@ns..." % ip)
ranges = itertools.chain(*[xrange(a, b+1) for (a,b) in config.rid[self.type]])
if not self.rid:
self.rid = config.rid[self.type][0][0] + ip.value - netaddr.IPNetwork(config.NETs[self.type][0]).value
if self.rid not in ranges:
raise ValueError("%s trop hors des plages prévues pour le réseau '%s'" % (ip, self.type))
if self.type == 'personnel-ens':
self.reste = self.rid & 0xff
else:
self.reste = self.rid & 0x7ff
return self.rid
def ipv4(self):
"""
Génère l'IPv4 associée à la machine
"""
if not self.ipv4_dispo:
raise ValueError("Pas d'adresse IPv4 disponible pour la machine %r" % self)
if not hasattr(self, '__ipv4'):
if self.type != "special":
net = netaddr.IPNetwork(config.NETs[self.type][0])
self.__ipv4 = netaddr.IPAddress(net.first + self.reste)
else:
self.__ipv4 = netaddr.IPAddress(config.rid_machines_speciales[self.rid])
return self.__ipv4
def ipv6_network(self):
"""
Génère le réseau /64 IPv6 associé à la machine
"""
if self.priv:
raise ValueError("Pas de prefix ipv6 disponible pour cette machine")
global_net = netaddr.IPNetwork(config.prefix["subnet"][0])
global_net.prefixlen = 64
return global_net.next(self.rid)
def __repr__(self):
if self.ipv4_dispo:
return "<Rid(rid=%s, ipv4='%s')>" % (self.rid, self.ipv4())
else:
return "<Rid(%s)>" % self.rid
def __int__(self):
return self.rid
def find_rid_plage(rid):
"""Trouve la plage du rid fourni"""
for (tp, plages) in config.rid_primaires.iteritems():
if isinstance(plages, list):
for begin, end in plages:
if begin <= rid <= end:
return tp, config.rid_primaires[tp][0]
else:
(begin, end) = plages
if begin <= rid <= end:
return tp, (begin, end)
else:
return "Inconnu", (0, 0)