@ -42,11 +42,7 @@ from django.contrib.auth.decorators import login_required
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
from django . db . models . signals import post_save
from django . dispatch import receiver
from django . utils . translation import ugettext as _
import tempfile
@ -106,7 +102,6 @@ from subprocess import (
)
from os . path import isfile
from os import remove
@login_required
@ -128,13 +123,17 @@ def index(request):
SortTable . TOPOLOGIE_INDEX
)
pagination_number = GeneralOption . get_cached_value ( ' pagination_number ' )
switch_list = re2o_paginator ( request , switch_list , pagination_number )
if any ( service_link . need_regen for service_link in Service_link . objects . filter ( service__service_type = ' graph_topo ' ) ) :
if any (
service_link . need_regen
for service_link in Service_link . objects . filter (
service__service_type = ' graph_topo ' )
) :
make_machine_graph ( )
for service_link in Service_link . objects . filter ( service__service_type = ' graph_topo ' ) :
for service_link in Service_link . objects . filter (
service__service_type = ' graph_topo ' ) :
service_link . done_regen ( )
if not isfile ( " /var/www/re2o/media/images/switchs.png " ) :
@ -150,8 +149,10 @@ def index(request):
@can_view_all ( PortProfile )
def index_port_profile ( request ) :
pagination_number = GeneralOption . get_cached_value ( ' pagination_number ' )
port_profile_list = PortProfile . objects . all ( ) . select_related ( ' vlan_untagged ' )
port_profile_list = re2o_paginator ( request , port_profile_list , pagination_number )
port_profile_list = PortProfile . objects . all ( ) . select_related (
' vlan_untagged ' )
port_profile_list = re2o_paginator (
request , port_profile_list , pagination_number )
return render (
request ,
' topologie/index_portprofile.html ' ,
@ -993,7 +994,8 @@ def new_port_profile(request):
@can_edit ( PortProfile )
def edit_port_profile ( request , port_profile , * * _kwargs ) :
""" Edit a port profile """
port_profile = EditPortProfileForm ( request . POST or None , instance = port_profile )
port_profile = EditPortProfileForm (
request . POST or None , instance = port_profile )
if port_profile . is_valid ( ) :
if port_profile . changed_data :
port_profile . save ( )
@ -1006,7 +1008,6 @@ def edit_port_profile(request, port_profile, **_kwargs):
)
@login_required
@can_delete ( PortProfile )
def del_port_profile ( request , port_profile , * * _kwargs ) :
@ -1026,13 +1027,14 @@ def del_port_profile(request, port_profile, **_kwargs):
request
)
def make_machine_graph ( ) :
"""
Create the graph of switchs , machines and access points .
"""
dico = {
' subs ' : [ ] ,
' links ' : [ ] ,
' links ' : [ ] ,
' alone ' : [ ] ,
' colors ' : {
' head ' : " #7f0505 " , # Color parameters for the graph
@ -1085,50 +1087,58 @@ def make_machine_graph():
dico [ ' subs ' ] [ - 1 ] [ ' machines ' ] . append ( {
' name ' : server . short_name ,
' switch ' : server . switch ( ) [ 0 ] . main_interface ( ) . domain . name ,
' port ' : Port . objects . filter ( machine_interface__machine = server ) [ 0 ] . port
' port ' : Port . objects . filter (
machine_interface__machine = server
) [ 0 ] . port
} )
# While the list of forgotten ones is not empty
while missing :
if missing [ 0 ] . ports . count ( ) : # The switch is not empty
links , new_detected = recursive_switchs ( missing [ 0 ] , None , [ missing [ 0 ] ] )
links , new_detected = recursive_switchs (
missing [ 0 ] , None , [ missing [ 0 ] ] )
for link in links :
dico [ ' links ' ] . append ( link )
# Update the lists of missings and already detected switchs
missing = [ i for i in missing if i not in new_detected ]
missing = [ i for i in missing if i not in new_detected ]
detected + = new_detected
else : # If the switch have no ports, don't explore it and hop to the next one
# If the switch have no ports, don't explore it and hop to the next one
else :
del missing [ 0 ]
# Switchs that are not connected or not in a building
for switch in Switch . objects . filter ( switchbay__isnull = True ) . exclude ( ports__related__isnull = False ) :
for switch in Switch . objects . filter (
switchbay__isnull = True ) . exclude ( ports__related__isnull = False ) :
dico [ ' alone ' ] . append ( {
' id ' : switch . id ,
' name ' : switch . main_interface ( ) . domain . name
} )
# generate the dot file
dot_data = generate_dot ( dico , ' topologie/graph_switch.dot ' )
dot_data = generate_dot ( dico , ' topologie/graph_switch.dot ' ) # generate the dot file
f = tempfile . NamedTemporaryFile ( mode = ' w+ ' , encoding = ' utf-8 ' , delete = False ) # Create a temporary file to store the dot data
# Create a temporary file to store the dot data
f = tempfile . NamedTemporaryFile ( mode = ' w+ ' , encoding = ' utf-8 ' , delete = False )
with f :
f . write ( dot_data )
unflatten = Popen ( # unflatten the graph to make it look better
[ " unflatten " , " -l " , " 3 " , f . name ] ,
[ " unflatten " , " -l " , " 3 " , f . name ] ,
stdout = PIPE
)
image = Popen ( # pipe the result of the first command into the second
Popen ( # pipe the result of the first command into the second
[ " dot " , " -Tpng " , " -o " , MEDIA_ROOT + " /images/switchs.png " ] ,
stdin = unflatten . stdout ,
stdout = PIPE
)
def generate_dot ( data , template ) :
def generate_dot ( data , template ) :
""" create the dot file
: param data : dictionary passed to the template
: param template : path to the dot template
: return : all the lines of the dot file """
t = loader . get_template ( template )
if not isinstance ( t , Template ) and not ( hasattr ( t , ' template ' ) and isinstance ( t . template , Template ) ) :
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 " )
@ -1136,27 +1146,40 @@ def generate_dot(data,template):
dot = t . render ( c )
return ( dot )
def recursive_switchs ( switch_start , switch_before , detected ) :
""" Visit the switch and travel to the switchs linked to it.
: param switch_start : the switch to begin the visit on
: param switch_before : the switch that you come from . None if switch_start is the first one
: param detected : list of all switchs already visited . None if switch_start is the first one
: return : A list of all the links found and a list of all the switchs visited """
: param switch_before : the switch that you come from .
None if switch_start is the first one
: param detected : list of all switchs already visited .
None if switch_start is the first one
: return : A list of all the links found and a list of
all the switchs visited
"""
detected . append ( switch_start )
links_return = [ ] # list of dictionaries of the links to be detected
for port in switch_start . ports . filter ( related__isnull = False ) : # create links to every switchs below
if port . related . switch != switch_before and port . related . switch != port . switch and port . related . switch not in detected : # Not the switch that we come from, not the current switch
links_return = [ ] # list of dictionaries of the links to be detected
# create links to every switchs below
for port in switch_start . ports . filter ( related__isnull = False ) :
# Not the switch that we come from, not the current switch
if port . related . switch != switch_before \
and port . related . switch != port . switch \
and port . related . switch not in detected :
links = { # Dictionary of a link
' depart ' : switch_start . id ,
' arrive ' : port . related . switch . id
' depart ' : switch_start . id ,
' arrive ' : port . related . switch . id
}
links_return . append ( links ) # Add current and below levels links
for port in switch_start . ports . filter ( related__isnull = False ) : # go down on every related switchs
if port . related . switch not in detected : # The switch at the end of this link has not been visited
links_down , detected = recursive_switchs ( port . related . switch , switch_start , detected ) # explore it and get the results
for link in links_down : # Add the non empty links to the current list
# go down on every related switchs
for port in switch_start . ports . filter ( related__isnull = False ) :
# The switch at the end of this link has not been visited
if port . related . switch not in detected :
# explore it and get the results
links_down , detected = recursive_switchs (
port . related . switch , switch_start , detected )
# Add the non empty links to the current list
for link in links_down :
if link :
links_return . append ( link )
return ( links_return , detected )