diff --git a/machines/migrations/0081_auto_20180511_1254.py b/machines/migrations/0081_auto_20180511_1254.py
new file mode 100644
index 00000000..8f7af9f7
--- /dev/null
+++ b/machines/migrations/0081_auto_20180511_1254.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-05-11 17:54
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0080_auto_20180502_2334'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='service_link',
+ name='server',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='machines.Interface'),
+ ),
+ ]
diff --git a/machines/models.py b/machines/models.py
index fe1923bb..4057bb16 100644
--- a/machines/models.py
+++ b/machines/models.py
@@ -1373,9 +1373,8 @@ class Service(RevMixin, AclMixin, models.Model):
def regen(service):
""" Fonction externe pour régérération d'un service, prend un objet service
en arg"""
- obj = Service.objects.filter(service_type=service)
- if obj:
- obj[0].ask_regen()
+ obj, created = Service.objects.get_or_create(service_type=service)
+ obj.ask_regen()
return
@@ -1384,7 +1383,12 @@ class Service_link(RevMixin, AclMixin, models.Model):
PRETTY_NAME = "Relation entre service et serveur"
service = models.ForeignKey('Service', on_delete=models.CASCADE)
- server = models.ForeignKey('Interface', on_delete=models.CASCADE)
+ server = models.ForeignKey(
+ 'Interface',
+ on_delete=models.CASCADE,
+ null=True,
+ blank=True
+ )
last_regen = models.DateTimeField(auto_now_add=True)
asked_regen = models.BooleanField(default=False)
@@ -1525,6 +1529,8 @@ def machine_post_save(**kwargs):
user.ldap_sync(base=False, access_refresh=False, mac_refresh=True)
regen('dhcp')
regen('mac_ip_list')
+ if user == preferences.models.OptionalMachine.get_cached_value('utilisateur_asso'):
+ regen('graph_topo')
@receiver(post_delete, sender=Machine)
@@ -1549,6 +1555,8 @@ def interface_post_save(**kwargs):
# Regen services
regen('dhcp')
regen('mac_ip_list')
+ if interface.machine.user == preferences.models.OptionalMachine.get_cached_value('utilisateur_asso'):
+ regen('graph_topo')
@receiver(post_delete, sender=Interface)
@@ -1659,3 +1667,11 @@ def srv_post_save(**_kwargs):
def srv_post_delete(**_kwargs):
"""Regeneration dns après modification d'un SRV"""
regen('dns')
+
+
+@receiver(post_save, sender=Service)
+def service_post_save(**kwargs):
+ """Création d'un service_link si non existant"""
+ service = kwargs['instance']
+ service_link, created = Service_link.objects.get_or_create(service=service)
+
diff --git a/media/images/__init__.py b/media/images/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/re2o/mixins.py b/re2o/mixins.py
index 2ee049cc..8895d099 100644
--- a/re2o/mixins.py
+++ b/re2o/mixins.py
@@ -24,6 +24,7 @@ A set of mixins used all over the project to avoid duplicating code
"""
from reversion import revisions as reversion
+from django.utils.functional import cached_property
from django.db import transaction
@@ -161,3 +162,5 @@ class AclMixin(object):
),
u"Vous n'avez pas le droit de voir des " + self.get_classname()
)
+
+
diff --git a/topologie/migrations/0060_server.py b/topologie/migrations/0060_server.py
new file mode 100644
index 00000000..802affcf
--- /dev/null
+++ b/topologie/migrations/0060_server.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-05-11 17:54
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0081_auto_20180511_1254'),
+ ('topologie', '0059_auto_20180415_2249'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Server',
+ fields=[
+ ],
+ options={
+ 'proxy': True,
+ },
+ bases=('machines.machine',),
+ ),
+ ]
diff --git a/topologie/models.py b/topologie/models.py
index 23b72b75..e1c945c7 100644
--- a/topologie/models.py
+++ b/topologie/models.py
@@ -40,7 +40,8 @@ from __future__ import unicode_literals
import itertools
from django.db import models
-from django.db.models.signals import post_save, post_delete
+from django.db.models.signals import pre_save, post_save, post_delete
+from django.utils.functional import cached_property
from django.dispatch import receiver
from django.core.exceptions import ValidationError
from django.db import IntegrityError
@@ -50,6 +51,11 @@ from reversion import revisions as reversion
from machines.models import Machine, regen
from re2o.mixins import AclMixin, RevMixin
+from os.path import isfile
+from os import remove
+
+
+
class Stack(AclMixin, RevMixin, models.Model):
"""Un objet stack. Regrouppe des switchs en foreign key
@@ -103,6 +109,70 @@ class AccessPoint(AclMixin, Machine):
("view_accesspoint", "Peut voir une borne"),
)
+ def port(self):
+ """Return the queryset of ports for this device"""
+ return Port.objects.filter(
+ machine_interface__machine=self
+ )
+
+ def switch(self):
+ """Return the switch where this is plugged"""
+ return Switch.objects.filter(
+ ports__machine_interface__machine=self
+ )
+
+ def building(self):
+ """Return the building of the AP/Server (building of the switchs connected to...)"""
+ return Building.objects.filter(
+ switchbay__switch=self.switch()
+ )
+
+ @cached_property
+ def short_name(self):
+ return str(self.interface_set.first().domain.name)
+
+ @classmethod
+ def all_ap_in(cls, building_instance):
+ """Get a building as argument, returns all ap of a building"""
+ return cls.objects.filter(interface__port__switch__switchbay__building=building_instance)
+
+ def __str__(self):
+ return str(self.interface_set.first())
+
+
+class Server(Machine):
+ """Dummy class, to retrieve servers of a building, or get switch of a server"""
+
+ class Meta:
+ proxy = True
+
+ def port(self):
+ """Return the queryset of ports for this device"""
+ return Port.objects.filter(
+ machine_interface__machine=self
+ )
+
+ def switch(self):
+ """Return the switch where this is plugged"""
+ return Switch.objects.filter(
+ ports__machine_interface__machine=self
+ )
+
+ def building(self):
+ """Return the building of the AP/Server (building of the switchs connected to...)"""
+ return Building.objects.filter(
+ switchbay__switch=self.switch()
+ )
+
+ @cached_property
+ def short_name(self):
+ return str(self.interface_set.first().domain.name)
+
+ @classmethod
+ def all_server_in(cls, building_instance):
+ """Get a building as argument, returns all server of a building"""
+ return cls.objects.filter(interface__port__switch__switchbay__building=building_instance).exclude(accesspoint__isnull=False)
+
def __str__(self):
return str(self.interface_set.first())
@@ -422,15 +492,47 @@ class Room(AclMixin, RevMixin, models.Model):
def ap_post_save(**_kwargs):
"""Regeneration des noms des bornes vers le controleur"""
regen('unifi-ap-names')
-
+ regen("graph_topo")
@receiver(post_delete, sender=AccessPoint)
def ap_post_delete(**_kwargs):
"""Regeneration des noms des bornes vers le controleur"""
regen('unifi-ap-names')
-
+ regen("graph_topo")
@receiver(post_delete, sender=Stack)
def stack_post_delete(**_kwargs):
"""Vide les id des switches membres d'une stack supprimée"""
Switch.objects.filter(stack=None).update(stack_member_id=None)
+
+@receiver(post_save, sender=Port)
+def port_post_save(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_delete, sender=Port)
+def port_post_delete(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_save, sender=ModelSwitch)
+def modelswitch_post_save(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_delete, sender=ModelSwitch)
+def modelswitch_post_delete(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_save, sender=Building)
+def building_post_save(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_delete, sender=Building)
+def building_post_delete(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_save, sender=Switch)
+def switch_post_save(**_kwargs):
+ regen("graph_topo")
+
+@receiver(post_delete, sender=Switch)
+def switch_post_delete(**_kwargs):
+ regen("graph_topo")
diff --git a/topologie/templates/topologie/graph_switch.dot b/topologie/templates/topologie/graph_switch.dot
new file mode 100644
index 00000000..46c6a766
--- /dev/null
+++ b/topologie/templates/topologie/graph_switch.dot
@@ -0,0 +1,135 @@
+{% block graph_dot %}
+strict digraph {
+graph [label="TOPOLOGIE DU RÉSEAU", labelloc=t, fontsize=40];
+node [fontname=Helvetica fontsize=8 shape=plaintext];
+edge[arrowhead=none];
+
+
+{% block subgraphs %}
+{% for sub in subs %}
+subgraph cluster_{{ sub.bat_id }} {
+fontsize=15;
+label="Batiment {{ sub.bat_name }}";
+
+{% if sub.bornes %}
+{% block bornes %}
+node [label=<
+
+
+
+ Borne |
+
+ Switch |
+
+ Port |
+
+{% for borne in sub.bornes %}
+
+
+ {{ borne.name }}
+ |
+
+ {{ borne.switch }}
+ |
+
+ {{ borne.port }}
+ |
+
+{% endfor %}
+
+>] {{sub.bat_name}}bornes;
+{% endblock %}
+{% endif %}
+
+{% if sub.machines %}
+{% block machines %}
+node [label=<
+
+
+
+ Machine |
+
+ Switch |
+
+ Port |
+
+
+{% for machine in sub.machines %}
+
+
+ {{ machine.name }}
+ |
+
+ {{ machine.switch }}
+ |
+
+ {{ machine.port }}
+ |
+
+{% endfor %}
+
+>] {{sub.bat_name}}machines;
+{% endblock %}
+{% endif %}
+
+
+{% block switchs %}
+{% for switch in sub.switchs %}
+node [label=<
+
+
+
+{{ switch.name }}
+ |
+
+Modèle
+ |
+
+{{ switch.model }}
+ |
+
+Taille
+ |
+
+{{ switch.nombre }}
+ |
+{% block liens %}
+{% for port in switch.ports %}
+
+{{ port.numero }}
+ |
+
+{{ port.related }}
+ |
+{% endfor %}
+{% endblock %}
+
+>] "{{ switch.id }}" ;
+{% endfor %}
+{% endblock %}
+}
+{% endfor %}
+{% endblock %}
+
+
+{% block isoles %}
+{% for switchs in alone %}
+"{{switchs.id}}" [label=<
+
+
+
+{{switchs.name}}
+ |
+
+>]
+{% endfor %}
+{% endblock %}
+
+
+{% block links %}
+{% for link in links %}
+"{{ link.depart }}" -> "{{ link.arrive }}";
+{% endfor %}
+{% endblock %}
+}
+{% endblock %}
\ No newline at end of file
diff --git a/topologie/templates/topologie/index.html b/topologie/templates/topologie/index.html
index 6e140251..a69d87d0 100644
--- a/topologie/templates/topologie/index.html
+++ b/topologie/templates/topologie/index.html
@@ -29,10 +29,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block title %}Switchs{% endblock %}
{% block content %}
+
+
+
+
+
+
-