mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 15:12:25 +00:00
Merge branch 'infra2.0'
This commit is contained in:
commit
a0605088b4
14 changed files with 407 additions and 12 deletions
|
@ -24,7 +24,10 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from reversion.admin import VersionAdmin
|
from reversion.admin import VersionAdmin
|
||||||
|
|
||||||
from .models import Port, Room, Switch
|
from .models import Port, Room, Switch, Stack
|
||||||
|
|
||||||
|
class StackAdmin(VersionAdmin):
|
||||||
|
list_display = ('name', 'stack_id', 'details')
|
||||||
|
|
||||||
class SwitchAdmin(VersionAdmin):
|
class SwitchAdmin(VersionAdmin):
|
||||||
list_display = ('switch_interface','location','number','details')
|
list_display = ('switch_interface','location','number','details')
|
||||||
|
@ -38,3 +41,4 @@ class RoomAdmin(VersionAdmin):
|
||||||
admin.site.register(Port, PortAdmin)
|
admin.site.register(Port, PortAdmin)
|
||||||
admin.site.register(Room, RoomAdmin)
|
admin.site.register(Room, RoomAdmin)
|
||||||
admin.site.register(Switch, SwitchAdmin)
|
admin.site.register(Switch, SwitchAdmin)
|
||||||
|
admin.site.register(Stack, StackAdmin)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
from .models import Port, Switch, Room
|
from .models import Port, Switch, Room, Stack
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from machines.models import Interface
|
from machines.models import Interface
|
||||||
|
|
||||||
|
@ -42,6 +42,11 @@ class AddPortForm(ModelForm):
|
||||||
class Meta(PortForm.Meta):
|
class Meta(PortForm.Meta):
|
||||||
fields = ['port', 'room', 'machine_interface', 'related', 'radius', 'details']
|
fields = ['port', 'room', 'machine_interface', 'related', 'radius', 'details']
|
||||||
|
|
||||||
|
class StackForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Stack
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
class EditSwitchForm(ModelForm):
|
class EditSwitchForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Switch
|
model = Switch
|
||||||
|
@ -54,9 +59,10 @@ class EditSwitchForm(ModelForm):
|
||||||
|
|
||||||
class NewSwitchForm(ModelForm):
|
class NewSwitchForm(ModelForm):
|
||||||
class Meta(EditSwitchForm.Meta):
|
class Meta(EditSwitchForm.Meta):
|
||||||
fields = ['location', 'number', 'details']
|
fields = ['location', 'number', 'details', 'stack', 'stack_member_id']
|
||||||
|
|
||||||
class EditRoomForm(ModelForm):
|
class EditRoomForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Room
|
model = Room
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
41
topologie/migrations/0023_auto_20170817_1654.py
Normal file
41
topologie/migrations/0023_auto_20170817_1654.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-08-17 14:54
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0022_auto_20161211_1622'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Stack',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(blank=True, max_length=32, null=True)),
|
||||||
|
('stack_id', models.CharField(max_length=32, unique=True)),
|
||||||
|
('details', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('member_id_min', models.IntegerField()),
|
||||||
|
('member_id_max', models.IntegerField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='switch',
|
||||||
|
name='stack_member_id',
|
||||||
|
field=models.IntegerField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='switch',
|
||||||
|
name='stack',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='topologie.Stack'),
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='switch',
|
||||||
|
unique_together=set([('stack', 'stack_member_id')]),
|
||||||
|
),
|
||||||
|
]
|
21
topologie/migrations/0024_auto_20170818_1021.py
Normal file
21
topologie/migrations/0024_auto_20170818_1021.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-08-18 08:21
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0023_auto_20170817_1654'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='switch',
|
||||||
|
name='stack',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='topologie.Stack'),
|
||||||
|
),
|
||||||
|
]
|
16
topologie/migrations/0025_merge_20170902_1242.py
Normal file
16
topologie/migrations/0025_merge_20170902_1242.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-09-02 10:42
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0024_auto_20170818_1021'),
|
||||||
|
('topologie', '0024_auto_20170826_1800'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
20
topologie/migrations/0026_auto_20170902_1245.py
Normal file
20
topologie/migrations/0026_auto_20170902_1245.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.7 on 2017-09-02 10:45
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('topologie', '0025_merge_20170902_1242'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='port',
|
||||||
|
name='radius',
|
||||||
|
field=models.CharField(choices=[('NO', 'NO'), ('STRICT', 'STRICT'), ('BLOQ', 'BLOQ'), ('COMMON', 'COMMON'), ('3', '3'), ('7', '7'), ('8', '8'), ('13', '13'), ('20', '20'), ('42', '42'), ('69', '69')], default='NO', max_length=32),
|
||||||
|
),
|
||||||
|
]
|
|
@ -21,6 +21,8 @@
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.signals import post_delete
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
@ -39,6 +41,29 @@ def clean_port_related(port):
|
||||||
related_port.related = None
|
related_port.related = None
|
||||||
related_port.save()
|
related_port.save()
|
||||||
|
|
||||||
|
class Stack(models.Model):
|
||||||
|
PRETTY_NAME = "Stack de switchs"
|
||||||
|
|
||||||
|
name = models.CharField(max_length=32, blank=True, null=True)
|
||||||
|
stack_id = models.CharField(max_length=32, unique=True)
|
||||||
|
details = models.CharField(max_length=255, blank=True, null=True)
|
||||||
|
member_id_min = models.IntegerField()
|
||||||
|
member_id_max = models.IntegerField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return " ".join([self.name, self.stack_id])
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.name:
|
||||||
|
self.name = self.stack_id
|
||||||
|
super(Stack, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
if self.member_id_max < self.member_id_min:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
raise ValidationError({'member_id_max':"L'id maximale est inférieure à l'id minimale"})
|
||||||
|
|
||||||
class Switch(models.Model):
|
class Switch(models.Model):
|
||||||
PRETTY_NAME = "Switch / Commutateur"
|
PRETTY_NAME = "Switch / Commutateur"
|
||||||
|
|
||||||
|
@ -46,10 +71,23 @@ class Switch(models.Model):
|
||||||
location = models.CharField(max_length=255)
|
location = models.CharField(max_length=255)
|
||||||
number = models.IntegerField()
|
number = models.IntegerField()
|
||||||
details = models.CharField(max_length=255, blank=True)
|
details = models.CharField(max_length=255, blank=True)
|
||||||
|
stack = models.ForeignKey(Stack, blank=True, null=True, on_delete=models.SET_NULL)
|
||||||
|
stack_member_id = models.IntegerField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('stack','stack_member_id')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.location) + ' ' + str(self.switch_interface)
|
return str(self.location) + ' ' + str(self.switch_interface)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
if self.stack is not None:
|
||||||
|
if self.stack_member_id is not None:
|
||||||
|
if (self.stack_member_id > self.stack.member_id_max) or (self.stack_member_id < self.stack.member_id_min):
|
||||||
|
raise ValidationError({'stack_member_id': "L'id de ce switch est en dehors des bornes permises pas la stack"})
|
||||||
|
else:
|
||||||
|
raise ValidationError({'stack_member_id': "L'id dans la stack ne peut être nul"})
|
||||||
|
|
||||||
class Port(models.Model):
|
class Port(models.Model):
|
||||||
PRETTY_NAME = "Port de switch"
|
PRETTY_NAME = "Port de switch"
|
||||||
STATES_BASE = (
|
STATES_BASE = (
|
||||||
|
@ -102,3 +140,6 @@ class Room(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.name)
|
return str(self.name)
|
||||||
|
|
||||||
|
@receiver(post_delete, sender=Stack)
|
||||||
|
def stack_post_delete(sender, **kwargs):
|
||||||
|
Switch.objects.filter(stack=None).update(stack_member_id = None)
|
||||||
|
|
53
topologie/templates/topologie/aff_stacks.html
Normal file
53
topologie/templates/topologie/aff_stacks.html
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{% comment %}
|
||||||
|
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
quelques clics.
|
||||||
|
|
||||||
|
Copyright © 2017 Gabriel Détraz
|
||||||
|
Copyright © 2017 Goulven Kermarec
|
||||||
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
|
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 2 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, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Stack</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Details</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for stack in stack_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{stack.name}}</td>
|
||||||
|
<td>{{stack.stack_id}}</td>
|
||||||
|
<td>{{stack.details}}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'stack' stack.pk %}">
|
||||||
|
<i class="glyphicon glyphicon-time"></i>
|
||||||
|
</a>
|
||||||
|
{% if is_infra %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-stack' stack.id %}">
|
||||||
|
<i class="glyphicon glyphicon-edit"></i>
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'topologie:del-stack' stack.pk %}">
|
||||||
|
<i class="glyphicon glyphicon-trash"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
|
@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<th>Ipv4</th>
|
<th>Ipv4</th>
|
||||||
<th>Localisation</th>
|
<th>Localisation</th>
|
||||||
<th>Ports</th>
|
<th>Ports</th>
|
||||||
|
<th>Stack</th>
|
||||||
|
<th>id interne Stack</th>
|
||||||
<th>Détails</th>
|
<th>Détails</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -43,6 +45,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<td>{{switch.switch_interface.ipv4}}</td>
|
<td>{{switch.switch_interface.ipv4}}</td>
|
||||||
<td>{{switch.location}}</td>
|
<td>{{switch.location}}</td>
|
||||||
<td>{{switch.number}}</td>
|
<td>{{switch.number}}</td>
|
||||||
|
<td>{{switch.stack.name}}</td>
|
||||||
|
<td>{{switch.stack_member_id}}</td>
|
||||||
<td>{{switch.details}}</td>
|
<td>{{switch.details}}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'switch' switch.pk %}">
|
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'switch' switch.pk %}">
|
||||||
|
|
53
topologie/templates/topologie/edit_stack_sw.html
Normal file
53
topologie/templates/topologie/edit_stack_sw.html
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{% comment %}
|
||||||
|
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
quelques clics.
|
||||||
|
|
||||||
|
Copyright © 2017 Gabriel Détraz
|
||||||
|
Copyright © 2017 Goulven Kermarec
|
||||||
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
|
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 2 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, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Stack</th>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Details</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for stack in stack_list %}
|
||||||
|
<tr>
|
||||||
|
<td>{{stack.name}}</td>
|
||||||
|
<td>{{stack.stack_id}}</td>
|
||||||
|
<td>{{stack.details}}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<a class="btn btn-info btn-sm" role="button" title="Historique" href="{% url 'topologie:history' 'stack' stack.pk %}">
|
||||||
|
<i class="glyphicon glyphicon-time"></i>
|
||||||
|
</a>
|
||||||
|
{% if is_infra %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'topologie:edit-stack' stack.id %}">
|
||||||
|
<i class="glyphicon glyphicon-edit"></i>
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-danger btn-sm" role="button" title="Supprimer" href="{% url 'topologie:del-stack' stack.pk %}">
|
||||||
|
<i class="glyphicon glyphicon-trash"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
39
topologie/templates/topologie/index_stack.html
Normal file
39
topologie/templates/topologie/index_stack.html
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{% extends "topologie/sidebar.html" %}
|
||||||
|
{% comment %}
|
||||||
|
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||||
|
se veut agnostique au réseau considéré, de manière à être installable en
|
||||||
|
quelques clics.
|
||||||
|
|
||||||
|
Copyright © 2017 Gabriel Détraz
|
||||||
|
Copyright © 2017 Goulven Kermarec
|
||||||
|
Copyright © 2017 Augustin Lemesle
|
||||||
|
|
||||||
|
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 2 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, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
|
{% block title %}Stacks{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Stacks</h2>
|
||||||
|
{% if is_infra %}
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'topologie:new-stack' %}"><i class="glyphicon glyphicon-plus"></i> Ajouter une stack</a>
|
||||||
|
{% endif %}
|
||||||
|
{% include "topologie/aff_stacks.html" with stack_list=stack_list %}
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
{% endblock %}
|
|
@ -33,4 +33,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
<i class="glyphicon glyphicon-list"></i>
|
<i class="glyphicon glyphicon-list"></i>
|
||||||
Switchs
|
Switchs
|
||||||
</a>
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-info" href="{% url "topologie:index-stack" %}">
|
||||||
|
<i class="glyphicon glyphicon-list"></i>
|
||||||
|
Stacks
|
||||||
|
</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -35,8 +35,13 @@ urlpatterns = [
|
||||||
url(r'^history/(?P<object>switch)/(?P<id>[0-9]+)$', views.history, name='history'),
|
url(r'^history/(?P<object>switch)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||||
url(r'^history/(?P<object>port)/(?P<id>[0-9]+)$', views.history, name='history'),
|
url(r'^history/(?P<object>port)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||||
url(r'^history/(?P<object>room)/(?P<id>[0-9]+)$', views.history, name='history'),
|
url(r'^history/(?P<object>room)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||||
|
url(r'^history/(?P<object>stack)/(?P<id>[0-9]+)$', views.history, name='history'),
|
||||||
url(r'^edit_port/(?P<port_id>[0-9]+)$', views.edit_port, name='edit-port'),
|
url(r'^edit_port/(?P<port_id>[0-9]+)$', views.edit_port, name='edit-port'),
|
||||||
url(r'^new_port/(?P<switch_id>[0-9]+)$', views.new_port, name='new-port'),
|
url(r'^new_port/(?P<switch_id>[0-9]+)$', views.new_port, name='new-port'),
|
||||||
url(r'^edit_switch/(?P<switch_id>[0-9]+)$', views.edit_switch, name='edit-switch'),
|
url(r'^edit_switch/(?P<switch_id>[0-9]+)$', views.edit_switch, name='edit-switch'),
|
||||||
|
url(r'^new_stack/$', views.new_stack, name='new-stack'),
|
||||||
|
url(r'^index_stack/$', views.index_stack, name='index-stack'),
|
||||||
|
url(r'^edit_stack/(?P<stack_id>[0-9]+)$', views.edit_stack, name='edit-stack'),
|
||||||
|
url(r'^del_stack/(?P<stack_id>[0-9]+)$', views.del_stack, name='del-stack'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,13 @@ from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models import ProtectedError
|
||||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
from reversion.models import Version
|
from reversion.models import Version
|
||||||
|
|
||||||
from topologie.models import Switch, Port, Room
|
from topologie.models import Switch, Port, Room, Stack
|
||||||
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm, AddPortForm, EditRoomForm
|
from topologie.forms import EditPortForm, NewSwitchForm, EditSwitchForm, AddPortForm, EditRoomForm, StackForm
|
||||||
from users.views import form
|
from users.views import form
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ from preferences.models import AssoOption, GeneralOption
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('cableur')
|
@permission_required('cableur')
|
||||||
def index(request):
|
def index(request):
|
||||||
switch_list = Switch.objects.order_by('location').select_related('switch_interface__domain__extension').select_related('switch_interface__ipv4').select_related('switch_interface__domain')
|
switch_list = Switch.objects.order_by('stack','stack_member_id','location').select_related('switch_interface__domain__extension').select_related('switch_interface__ipv4').select_related('switch_interface__domain')
|
||||||
return render(request, 'topologie/index.html', {'switch_list': switch_list})
|
return render(request, 'topologie/index.html', {'switch_list': switch_list})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -65,6 +66,12 @@ def history(request, object, id):
|
||||||
except Room.DoesNotExist:
|
except Room.DoesNotExist:
|
||||||
messages.error(request, "Chambre inexistante")
|
messages.error(request, "Chambre inexistante")
|
||||||
return redirect("/topologie/")
|
return redirect("/topologie/")
|
||||||
|
elif object == 'stack':
|
||||||
|
try:
|
||||||
|
object_instance = Stack.objects.get(pk=id)
|
||||||
|
except Room.DoesNotExist:
|
||||||
|
messages.error(request, "Stack inexistante")
|
||||||
|
return redirect("/topologie/")
|
||||||
else:
|
else:
|
||||||
messages.error(request, "Objet inconnu")
|
messages.error(request, "Objet inconnu")
|
||||||
return redirect("/topologie/")
|
return redirect("/topologie/")
|
||||||
|
@ -100,6 +107,13 @@ def index_room(request):
|
||||||
room_list = Room.objects.order_by('name')
|
room_list = Room.objects.order_by('name')
|
||||||
return render(request, 'topologie/index_room.html', {'room_list': room_list})
|
return render(request, 'topologie/index_room.html', {'room_list': room_list})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('infra')
|
||||||
|
def index_stack(request):
|
||||||
|
stack_list = Stack.objects.order_by('name')
|
||||||
|
return render(request, 'topologie/index_stack.html', {'stack_list': stack_list})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('infra')
|
@permission_required('infra')
|
||||||
def new_port(request, switch_id):
|
def new_port(request, switch_id):
|
||||||
|
@ -141,6 +155,77 @@ def edit_port(request, port_id):
|
||||||
return redirect("/topologie/switch/" + str(port_object.switch.id))
|
return redirect("/topologie/switch/" + str(port_object.switch.id))
|
||||||
return form({'topoform':port}, 'topologie/topo.html', request)
|
return form({'topoform':port}, 'topologie/topo.html', request)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('infra')
|
||||||
|
def new_stack(request):
|
||||||
|
stack = StackForm(request.POST or None)
|
||||||
|
#if stack.is_valid():
|
||||||
|
if request.POST:
|
||||||
|
try:
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
stack.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Création")
|
||||||
|
messages.success(request, "Stack crée")
|
||||||
|
except:
|
||||||
|
messages.error(request, "Cette stack existe déjà")
|
||||||
|
return form({'topoform':stack}, 'topologie/topo.html', request)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('infra')
|
||||||
|
def edit_stack(request,stack_id):
|
||||||
|
try:
|
||||||
|
stack = Stack.objects.get(pk=stack_id)
|
||||||
|
except Stack.DoesNotExist:
|
||||||
|
messages.error(request, u"Stack inexistante")
|
||||||
|
return redirect('/topologie/index_stack/')
|
||||||
|
stack = StackForm(request.POST or None, instance=stack)
|
||||||
|
if stack.is_valid():
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
stack.save()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in stack.changed_data))
|
||||||
|
return redirect('/topologie/index_stack')
|
||||||
|
return form({'topoform':stack}, 'topologie/topo.html', request)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('infra')
|
||||||
|
def del_stack(request,stack_id):
|
||||||
|
try:
|
||||||
|
stack = Stack.objects.get(pk=stack_id)
|
||||||
|
except Stack.DoesNotExist:
|
||||||
|
messages.error(request, u"Stack inexistante")
|
||||||
|
return redirect('/topologie/index_stack')
|
||||||
|
if request.method == "POST":
|
||||||
|
try:
|
||||||
|
with transaction.atomic(), reversion.create_revision():
|
||||||
|
stack.delete()
|
||||||
|
reversion.set_user(request.user)
|
||||||
|
reversion.set_comment("Destruction")
|
||||||
|
messages.success(request, "La stack a eté détruite")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "La stack %s est affectée à un autre objet, impossible de la supprimer" % stack)
|
||||||
|
return redirect('/topologie/index_stack')
|
||||||
|
return form({'objet':stack}, 'topologie/delete.html', request)
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('infra')
|
||||||
|
def edit_switchs_stack(request,stack_id):
|
||||||
|
try:
|
||||||
|
stack = Stack.objects.get(pk=stack_id)
|
||||||
|
except Stack.DoesNotExist:
|
||||||
|
messages.error(request, u"Stack inexistante")
|
||||||
|
return redirect('/topologie/index_stack')
|
||||||
|
if request.method == "POST":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
context = {'stack': stack}
|
||||||
|
context['switchs_stack'] = stack.switchs_set.all()
|
||||||
|
context['switchs_autres'] = Switch.object.filter(stack=None)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('infra')
|
@permission_required('infra')
|
||||||
def new_switch(request):
|
def new_switch(request):
|
||||||
|
@ -259,10 +344,13 @@ def del_room(request, room_id):
|
||||||
messages.error(request, u"Chambre inexistante" )
|
messages.error(request, u"Chambre inexistante" )
|
||||||
return redirect("/topologie/index_room/")
|
return redirect("/topologie/index_room/")
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
try:
|
||||||
with transaction.atomic(), reversion.create_revision():
|
with transaction.atomic(), reversion.create_revision():
|
||||||
room.delete()
|
room.delete()
|
||||||
reversion.set_user(request.user)
|
reversion.set_user(request.user)
|
||||||
reversion.set_comment("Destruction")
|
reversion.set_comment("Destruction")
|
||||||
messages.success(request, "La chambre/prise a été détruite")
|
messages.success(request, "La chambre/prise a été détruite")
|
||||||
|
except ProtectedError:
|
||||||
|
messages.error(request, "La chambre %s est affectée à un autre objet, impossible de la supprimer (switch ou user)" % room)
|
||||||
return redirect("/topologie/index_room/")
|
return redirect("/topologie/index_room/")
|
||||||
return form({'objet': room, 'objet_name': 'Chambre'}, 'topologie/delete.html', request)
|
return form({'objet': room, 'objet_name': 'Chambre'}, 'topologie/delete.html', request)
|
||||||
|
|
Loading…
Reference in a new issue