diff --git a/machines/admin.py b/machines/admin.py
index fa6262ac..8c0ef947 100644
--- a/machines/admin.py
+++ b/machines/admin.py
@@ -23,7 +23,7 @@
from django.contrib import admin
from reversion.admin import VersionAdmin
-from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns
+from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Service
class MachineAdmin(VersionAdmin):
list_display = ('user','name','active')
@@ -53,6 +53,9 @@ class InterfaceAdmin(VersionAdmin):
class DomainAdmin(VersionAdmin):
list_display = ('interface_parent', 'name', 'extension', 'cname')
+class ServiceAdmin(VersionAdmin):
+ list_display = ('service_type', 'time_regen')
+
admin.site.register(Machine, MachineAdmin)
admin.site.register(MachineType, MachineTypeAdmin)
admin.site.register(IpType, IpTypeAdmin)
@@ -62,3 +65,4 @@ admin.site.register(Ns, NsAdmin)
admin.site.register(IpList, IpListAdmin)
admin.site.register(Interface, InterfaceAdmin)
admin.site.register(Domain, DomainAdmin)
+admin.site.register(Service, ServiceAdmin)
diff --git a/machines/forms.py b/machines/forms.py
index bd71732d..668f8ac3 100644
--- a/machines/forms.py
+++ b/machines/forms.py
@@ -22,7 +22,7 @@
from django.forms import ModelForm, Form, ValidationError
from django import forms
-from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, IpType
+from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Service, IpType
from django.db.models import Q
from django.core.validators import validate_email
@@ -141,13 +141,9 @@ class MachineTypeForm(ModelForm):
self.fields['type'].label = 'Type de machine à ajouter'
self.fields['ip_type'].label = "Type d'ip relié"
-class DelMachineTypeForm(ModelForm):
+class DelMachineTypeForm(Form):
machinetypes = forms.ModelMultipleChoiceField(queryset=MachineType.objects.all(), label="Types de machines actuelles", widget=forms.CheckboxSelectMultiple)
- class Meta:
- exclude = ['type','ip_type']
- model = MachineType
-
class IpTypeForm(ModelForm):
class Meta:
model = IpType
@@ -161,7 +157,7 @@ class EditIpTypeForm(IpTypeForm):
class Meta(IpTypeForm.Meta):
fields = ['extension','type','need_infra']
-class DelIpTypeForm(forms.Form):
+class DelIpTypeForm(Form):
iptypes = forms.ModelMultipleChoiceField(queryset=IpType.objects.all(), label="Types d'ip actuelles", widget=forms.CheckboxSelectMultiple)
class ExtensionForm(ModelForm):
@@ -190,13 +186,9 @@ class MxForm(ModelForm):
super(MxForm, self).__init__(*args, **kwargs)
self.fields['name'].queryset = Domain.objects.exclude(interface_parent=None)
-class DelMxForm(ModelForm):
+class DelMxForm(Form):
mx = forms.ModelMultipleChoiceField(queryset=Mx.objects.all(), label="MX actuels", widget=forms.CheckboxSelectMultiple)
- class Meta:
- exclude = ['zone', 'priority', 'name']
- model = Mx
-
class NsForm(ModelForm):
class Meta:
model = Ns
@@ -206,9 +198,21 @@ class NsForm(ModelForm):
super(NsForm, self).__init__(*args, **kwargs)
self.fields['ns'].queryset = Domain.objects.exclude(interface_parent=None)
-class DelNsForm(ModelForm):
+class DelNsForm(Form):
ns = forms.ModelMultipleChoiceField(queryset=Ns.objects.all(), label="Enregistrements NS actuels", widget=forms.CheckboxSelectMultiple)
+class ServiceForm(ModelForm):
class Meta:
- exclude = ['zone', 'ns']
- model = Ns
+ model = Service
+ fields = '__all__'
+
+ def save(self, commit=True):
+ instance = super(ServiceForm, self).save(commit=False)
+ if commit:
+ instance.save()
+ instance.process_link(self.cleaned_data.get('servers'))
+ return instance
+
+class DelServiceForm(Form):
+ service = forms.ModelMultipleChoiceField(queryset=Service.objects.all(), label="Services actuels", widget=forms.CheckboxSelectMultiple)
+
diff --git a/machines/migrations/0044_auto_20170808_0233.py b/machines/migrations/0044_auto_20170808_0233.py
new file mode 100644
index 00000000..864505a2
--- /dev/null
+++ b/machines/migrations/0044_auto_20170808_0233.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-08-08 00:33
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0043_auto_20170721_0350'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Service',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('service_type', models.CharField(blank=True, max_length=255, unique=True)),
+ ('time_regen', models.DurationField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Service_link',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('last_regen', models.DateTimeField()),
+ ('asked_regen', models.BooleanField()),
+ ('server', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.Interface')),
+ ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='machines.Service')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='service',
+ name='servers',
+ field=models.ManyToManyField(through='machines.Service_link', to='machines.Interface'),
+ ),
+ ]
diff --git a/machines/migrations/0045_auto_20170808_0348.py b/machines/migrations/0045_auto_20170808_0348.py
new file mode 100644
index 00000000..16a6bb0a
--- /dev/null
+++ b/machines/migrations/0045_auto_20170808_0348.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2017-08-08 01:48
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0044_auto_20170808_0233'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='service_link',
+ name='asked_regen',
+ field=models.BooleanField(default=False),
+ ),
+ migrations.AlterField(
+ model_name='service_link',
+ name='last_regen',
+ field=models.DateTimeField(auto_now_add=True),
+ ),
+ ]
diff --git a/machines/models.py b/machines/models.py
index d41bc6bb..44f0163f 100644
--- a/machines/models.py
+++ b/machines/models.py
@@ -25,6 +25,7 @@ from django.db.models.signals import post_save, pre_delete, post_delete
from django.dispatch import receiver
from django.forms import ValidationError
from django.utils.functional import cached_property
+from django.utils import timezone
from macaddress.fields import MACAddressField
from netaddr import mac_bare, EUI, IPSet, IPNetwork
from django.core.validators import MinValueValidator,MaxValueValidator
@@ -269,6 +270,48 @@ class IpList(models.Model):
def __str__(self):
return self.ipv4
+class Service(models.Model):
+ """ Definition d'un service (dhcp, dns, etc)"""
+ service_type = models.CharField(max_length=255, blank=True, unique=True)
+ time_regen = models.DurationField()
+ servers = models.ManyToManyField('Interface', through='Service_link')
+
+ def ask_regen(self):
+ for serv in Service_link.objects.filter(service=self):
+ serv.asked_regen = True
+ serv.save()
+
+ def process_link(self, servers):
+ for serv in servers.exclude(pk__in=Interface.objects.filter(service=self)):
+ link = Service_link(service=self, server=serv)
+ link.save()
+ for serv in Service_link.objects.filter(service=self).exclude(server__in=servers):
+ serv.delete()
+ return
+
+ def save(self, *args, **kwargs):
+ super(Service, self).save(*args, **kwargs)
+
+ def __str__(self):
+ return str(self.service_type)
+
+class Service_link(models.Model):
+ """ Definition du lien entre serveurs et services"""
+ service = models.ForeignKey('Service', on_delete=models.CASCADE)
+ server = models.ForeignKey('Interface', on_delete=models.CASCADE)
+ last_regen = models.DateTimeField(auto_now_add=True)
+ asked_regen = models.BooleanField(default=False)
+
+
+ def need_regen(self):
+ if self.asked_regen and (self.last_regen + self.service.time_regen) > timezone.now():
+ return True
+ else:
+ return False
+
+ def __str__(self):
+ return str(self.server) + " " + str(self.service)
+
@receiver(post_save, sender=Machine)
def machine_post_save(sender, **kwargs):
user = kwargs['instance'].user
diff --git a/machines/templates/machines/aff_servers.html b/machines/templates/machines/aff_servers.html
new file mode 100644
index 00000000..f29b620f
--- /dev/null
+++ b/machines/templates/machines/aff_servers.html
@@ -0,0 +1,47 @@
+{% 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 %}
+
+
+
+
+ Nom du service |
+ Serveur |
+ Dernière régénération |
+ Régénération nécessaire |
+ Régénération activée |
+
+
+ {% for server in servers_list %}
+
+ {{ server.service }} |
+ {{ server.server }} |
+ {{ server.last_regen }} |
+ {{ server.asked_regen }} |
+ {{ server.need_regen }} |
+
+ |
+
+ {% endfor %}
+
+
diff --git a/machines/templates/machines/aff_service.html b/machines/templates/machines/aff_service.html
new file mode 100644
index 00000000..f7f2b3f8
--- /dev/null
+++ b/machines/templates/machines/aff_service.html
@@ -0,0 +1,49 @@
+{% 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 %}
+
+
+
+
+ Nom du service |
+ Temps minimum de régénération |
+ Serveurs inclus |
+ |
+ |
+
+
+ {% for service in service_list %}
+
+ {{ service.service_type }} |
+ {{ service.time_regen }} |
+ {% for serv in service.servers.all %}{{ serv }}, {% endfor %} |
+
+ {% if is_infra %}
+ {% include 'buttons/edit.html' with href='machines:edit-service' id=service.id %}
+ {% endif %}
+ {% include 'buttons/history.html' with href='machines:history' name='service' id=service.id %}
+ |
+
+ {% endfor %}
+
+
diff --git a/machines/templates/machines/index_service.html b/machines/templates/machines/index_service.html
new file mode 100644
index 00000000..b07f994c
--- /dev/null
+++ b/machines/templates/machines/index_service.html
@@ -0,0 +1,43 @@
+{% extends "machines/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 %}Machines{% endblock %}
+
+{% block content %}
+ Liste des services
+ {% if is_infra %}
+ Ajouter un service
+ Supprimer un ou plusieurs service
+ {% endif %}
+ {% include "machines/aff_service.html" with service_list=service_list %}
+ Etat des serveurs
+ {% include "machines/aff_servers.html" with servers_list=servers_list %}
+
+
+
+{% endblock %}
+
diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html
index 8261de3a..c4d98448 100644
--- a/machines/templates/machines/sidebar.html
+++ b/machines/templates/machines/sidebar.html
@@ -42,5 +42,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Plages d'IP
+
+
+ Services (dhcp, dns...)
+
{% endif %}
{% endblock %}
diff --git a/machines/urls.py b/machines/urls.py
index 65128581..1b352139 100644
--- a/machines/urls.py
+++ b/machines/urls.py
@@ -52,6 +52,10 @@ urlpatterns = [
url(r'^edit_alias/(?P[0-9]+)$', views.edit_alias, name='edit-alias'),
url(r'^del_alias/(?P[0-9]+)$', views.del_alias, name='del-alias'),
url(r'^index_alias/(?P[0-9]+)$', views.index_alias, name='index-alias'),
+ url(r'^add_service/$', views.add_service, name='add-service'),
+ url(r'^edit_service/(?P[0-9]+)$', views.edit_service, name='edit-service'),
+ url(r'^del_service/$', views.del_service, name='del-service'),
+ url(r'^index_service/$', views.index_service, name='index-service'),
url(r'^history/(?P