@ -43,6 +43,10 @@ from django.db import IntegrityError
from django . db . models import ProtectedError , Prefetch
from django . core . exceptions import ValidationError
from django . contrib . staticfiles . storage import staticfiles_storage
from django . template . loader import get_template
from django . template import Context , Template , loader
import pprint
from users . views import form
from re2o . utils import re2o_paginator , SortTable
@ -940,93 +944,78 @@ def make_machine_graph():
"""
Crée le fichier dot et l ' image du graph des Switchs
"""
#Syntaxe DOT temporaire, A mettre dans un template:
lignes = [ ''' digraph Switchs {
node [
fontname = Helvetica
fontsize = 8
shape = plaintext ]
edge [ arrowhead = odot , arrowtail = dot ] ''' ]
node_fixe = ''' node [label=<
< TABLE BGCOLOR = " palegoldenrod " BORDER = " 0 " CELLBORDER = " 0 " CELLSPACING = " 0 " >
< TR > < TD COLSPAN = " 2 " CELLPADDING = " 4 " ALIGN = " CENTER " BGCOLOR = " olivedrab4 " >
< FONT FACE = " Helvetica Bold " COLOR = " white " >
{ }
< / FONT > < / TD > < / TR >
< TR > < TD ALIGN = " LEFT " BORDER = " 0 " >
< FONT COLOR = " #7B7B7B " > { } < / FONT >
< / TD >
< TD ALIGN = " LEFT " >
< FONT COLOR = " #7B7B7B " > { } < / FONT >
< / TD > < / TR >
< TR > < TD ALIGN = " LEFT " BORDER = " 0 " >
< FONT COLOR = " #7B7B7B " > { } < / FONT >
< / TD >
< TD ALIGN = " LEFT " >
< FONT > { } < / FONT >
< / TD > < / TR > '''
node_ports = ''' <TR><TD ALIGN= " LEFT " BORDER= " 0 " >
< FONT COLOR = " #7B7B7B " > { } < / FONT >
< / TD >
< TD ALIGN = " LEFT " >
< FONT > { } < / FONT >
< / TD > < / TR > '''
cluster = ''' subgraph cluster_ {} {{
color = blue ;
label = " Batiment {} " ; '''
end_table = ''' </TABLE>
> ] \" {} _ {} \" ; ' ' '
switch_alone = ''' {} [label=<
< TABLE BGCOLOR = " palegoldenrod " BORDER = " 0 " CELLBORDER = " 0 " CELLSPACING = " 0 " >
< TR > < TD COLSPAN = " 2 " CELLPADDING = " 4 " ALIGN = " CENTER " BGCOLOR = " olivedrab4 " >
< FONT FACE = " Helvetica Bold " COLOR = " white " >
{ }
< / FONT > < / TD > < / TR >
< / TABLE >
> ] '''
dico = { ' subs ' : [ ] , ' links ' : [ ] , ' alone ' : [ ] }
missing = [ ]
detected = [ ]
for sw in Switch . objects . all ( ) :
if ( sw not in detected ) :
missing . append ( sw )
for building in Building . objects . all ( ) :
lignes . append ( cluster . format ( len ( lignes ) , building ) )
for switch in Switch . objects . filter ( switchbay__building = building ) :
lignes . append ( node_fixe . format ( switch . main_interface ( ) . domain . name , " Modèle " , switch . model , " Nombre de ports " , switch . number ) )
for p in switch . ports . all ( ) . filter ( related__isnull = False ) :
lignes . append ( node_ports . format ( p . port , p . related . switch . main_interface ( ) . domain . name ) )
lignes . append ( end_table . format ( building . id , switch . id ) )
lignes . append ( " } " )
while ( missing != [ ] ) :
lignes , new_detected = recursive_switchs ( missing [ 0 ] . ports . all ( ) . filter ( related = None ) . first ( ) , None , lignes , [ missing [ 0 ] ] )
for building in Building . objects . all ( ) : #Parcour tous les batiments
dico [ ' subs ' ] . append ( { ' bat_id ' : building . id , ' bat_name ' : building , ' switchs ' : [ ] } )
for switch in Switch . objects . filter ( switchbay__building = building ) : #Parcour tous les switchs de ce batiment
dico [ ' subs ' ] [ - 1 ] [ ' switchs ' ] . append ( { ' name ' : switch . main_interface ( ) . domain . name , ' nombre ' : switch . number , ' model ' : switch . model , ' id ' : switch . id , ' batiment ' : building , ' ports ' : [ ] } )
for p in switch . ports . all ( ) . filter ( related__isnull = False ) : #Parcour tout les ports liés de ce switch
dico [ ' subs ' ] [ - 1 ] [ ' switchs ' ] [ - 1 ] [ ' ports ' ] . append ( { ' numero ' : p . port , ' related ' : p . related . switch . main_interface ( ) . domain . name } )
while ( missing != [ ] ) : #Tant que la liste des oubliés n'est pas vide i.e on les a pas tous passer
links , new_detected = recursive_switchs ( missing [ 0 ] . ports . all ( ) . filter ( related = None ) . first ( ) , None , [ missing [ 0 ] ] )
for link in links :
dico [ ' links ' ] . append ( link )
#on recrée la liste des oubliés et des detectés
missing = [ i for i in missing if i not in new_detected ]
detected + = new_detected
for switch in Switch . objects . all ( ) . filter ( switchbay__isnull = True ) . exclude ( ports__related__isnull = False ) :
lignes . append ( switch_alone . format ( switch . id , switch . main_interface ( ) . domain . name ) )
lignes . append ( " } " )
for switch in Switch . objects . all ( ) . filter ( switchbay__isnull = True ) . exclude ( ports__related__isnull = False ) : #Tous ceux qui ne sont ni connectés ni dans un batiment
dico [ ' alone ' ] . append ( { ' id ' : switch . id , ' name ' : switch . main_interface ( ) . domain . name } )
dot_data = generate_image ( dico )
fichier = open ( " media/images/switchs.dot " , " w " )
for ligne in lignes :
fichier . write ( ligne + " \n " )
fichier . write ( dot_data )
fichier . close ( )
unflatten = Popen ( [ " unflatten " , " -l " , " 3 " , " media/images/switchs.dot " ] , stdout = PIPE )
image = Popen ( [ " dot " , " -Tpng " , " -o " , " media/images/switchs.png " ] , stdin = unflatten . stdout , stdout = PIPE )
def generate_image ( data , template = ' topologie/graph_switch.dot ' ) :
t = loader . get_template ( template )
def recursive_switchs ( port_start , switch_before , lignes , detected ) :
if not isinstance ( t , Template ) and not ( hasattr ( t , ' template ' ) and isinstance ( t . template , Template ) ) :
raise Exception ( " Le template par défaut de Django n ' est pas utilisé. "
" Cela peut mener à des erreurs de rendu. "
" Vérifiez les paramètres " )
c = Context ( data ) . flatten ( )
dot = t . render ( c )
return ( dot )
def recursive_switchs ( port_start , switch_before , detected ) :
"""
Parcour récursivement le switchs auquel appartient port_start pour trouver les ports suivants liés
"""
l_ports = port_start . switch . ports . filter ( related__isnull = False )
links_return = [ ] #Liste de dictionaires qui stockes les nouveaux liens détéctés
l_ports = port_start . switch . ports . filter ( related__isnull = False ) #Liste des ports dont le related est non null
for port in l_ports :
if port . related . switch != switch_before and port . related . switch != port . switch :
links = [ ]
for sw in [ switch for switch in [ port_start . switch , port . related . switch ] ] :
if ( sw not in detected ) :
detected . append ( sw )
if ( sw . switchbay . building ) :
links . append ( " \" {} _ {} \" " . format ( sw . switchbay . building . id , sw . id ) )
else :
links . append ( " \" {} \" " . format ( sw . id ) )
lignes . append ( links [ 0 ] + " -> " + links [ 1 ] )
lignes , detected = recursive_switchs ( port . related , port_start . switch , lignes , detected )
return ( lignes , detected )
if port . related . switch != switch_before and port . related . switch != port . switch : #Pas le switch dont on vient, pas le switch actuel
detected . append ( port_start . switch )
detected . append ( port . related . switch )
links = { ' depart ' : port_start . switch . id , ' arrive ' : port . related . switch . id }
links_down , detected = recursive_switchs ( port . related , port_start . switch , detected )
links_return . append ( links )
for link in links_down :
if ( link != [ ] ) :
links_return . append ( link )
return ( links_return , detected )