From a8d009c035cd25ac507e5b206bac716261b10dbc Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 5 Sep 2017 18:18:41 +0200 Subject: [PATCH] Ajoute un champ text --- machines/admin.py | 7 +- machines/forms.py | 10 ++- machines/migrations/0053_text.py | 23 ++++++ machines/migrations/0054_text_zone.py | 22 ++++++ machines/models.py | 14 ++++ machines/serializers.py | 16 ++++- machines/templates/machines/aff_text.html | 48 +++++++++++++ .../templates/machines/index_extension.html | 6 ++ machines/templates/machines/sidebar.html | 2 +- machines/urls.py | 5 ++ machines/views.py | 71 +++++++++++++++++-- 11 files changed, 216 insertions(+), 8 deletions(-) create mode 100644 machines/migrations/0053_text.py create mode 100644 machines/migrations/0054_text_zone.py create mode 100644 machines/templates/machines/aff_text.html diff --git a/machines/admin.py b/machines/admin.py index c9559fe5..ee016831 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, Vlan, Service +from .models import IpType, Machine, MachineType, Domain, IpList, Interface, Extension, Mx, Ns, Vlan, Text, Service class MachineAdmin(VersionAdmin): pass @@ -46,6 +46,10 @@ class MxAdmin(VersionAdmin): class NsAdmin(VersionAdmin): pass +class TextAdmin(VersionAdmin): + pass + + class IpListAdmin(VersionAdmin): pass @@ -64,6 +68,7 @@ admin.site.register(IpType, IpTypeAdmin) admin.site.register(Extension, ExtensionAdmin) admin.site.register(Mx, MxAdmin) admin.site.register(Ns, NsAdmin) +admin.site.register(Text, TextAdmin) admin.site.register(IpList, IpListAdmin) admin.site.register(Interface, InterfaceAdmin) admin.site.register(Domain, DomainAdmin) diff --git a/machines/forms.py b/machines/forms.py index dedd8395..5a2de206 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, Service, Vlan, IpType +from .models import Domain, Machine, Interface, IpList, MachineType, Extension, Mx, Text, Ns, Service, Vlan, IpType from django.db.models import Q from django.core.validators import validate_email @@ -194,6 +194,14 @@ class NsForm(ModelForm): class DelNsForm(Form): ns = forms.ModelMultipleChoiceField(queryset=Ns.objects.all(), label="Enregistrements NS actuels", widget=forms.CheckboxSelectMultiple) +class TextForm(ModelForm): + class Meta: + model = Text + fields = '__all__' + +class DelTextForm(Form): + text = forms.ModelMultipleChoiceField(queryset=Text.objects.all(), label="Enregistrements Text actuels", widget=forms.CheckboxSelectMultiple) + class ServiceForm(ModelForm): class Meta: model = Service diff --git a/machines/migrations/0053_text.py b/machines/migrations/0053_text.py new file mode 100644 index 00000000..ee7679fc --- /dev/null +++ b/machines/migrations/0053_text.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-05 15:38 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0052_auto_20170828_2322'), + ] + + operations = [ + migrations.CreateModel( + name='Text', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('field1', models.CharField(max_length=255)), + ('field2', models.CharField(max_length=255)), + ], + ), + ] diff --git a/machines/migrations/0054_text_zone.py b/machines/migrations/0054_text_zone.py new file mode 100644 index 00000000..f3447f35 --- /dev/null +++ b/machines/migrations/0054_text_zone.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-09-05 15:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0053_text'), + ] + + operations = [ + migrations.AddField( + model_name='text', + name='zone', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='machines.Extension'), + preserve_default=False, + ), + ] diff --git a/machines/models.py b/machines/models.py index e35515e6..ccada7d6 100644 --- a/machines/models.py +++ b/machines/models.py @@ -167,6 +167,20 @@ class Ns(models.Model): def __str__(self): return str(self.zone) + ' ' + str(self.ns) +class Text(models.Model): + PRETTY_NAME = "Enregistrement text" + + zone = models.ForeignKey('Extension', on_delete=models.PROTECT) + field1 = models.CharField(max_length=255) + field2 = models.CharField(max_length=255) + + def __str__(self): + return str(self.zone) + " : " + str(self.field1) + " " + str(self.field2) + + @cached_property + def dns_entry(self): + return str(self.field1) + " IN TXT " + str(self.field2) + class Interface(models.Model): PRETTY_NAME = "Interface" diff --git a/machines/serializers.py b/machines/serializers.py index 326f27f7..329bffa7 100644 --- a/machines/serializers.py +++ b/machines/serializers.py @@ -23,7 +23,7 @@ #Augustin Lemesle from rest_framework import serializers -from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Mx, Service_link, Ns +from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Text, Mx, Service_link, Ns class IpTypeField(serializers.RelatedField): def to_representation(self, value): @@ -90,6 +90,20 @@ class MxSerializer(serializers.ModelSerializer): def get_zone_name(self, obj): return obj.zone.name +class TextSerializer(serializers.ModelSerializer): + zone = serializers.SerializerMethodField('get_zone_name') + text = serializers.SerializerMethodField('get_text_name') + + class Meta: + model = Text + fields = ('zone','text') + + def get_zone_name(self, obj): + return str(obj.zone.name) + + def get_text_name(self, obj): + return str(obj.dns_entry) + class NsSerializer(serializers.ModelSerializer): zone = serializers.SerializerMethodField('get_zone_name') ns = serializers.SerializerMethodField('get_domain_name') diff --git a/machines/templates/machines/aff_text.html b/machines/templates/machines/aff_text.html new file mode 100644 index 00000000..f3ada132 --- /dev/null +++ b/machines/templates/machines/aff_text.html @@ -0,0 +1,48 @@ +{% 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 %} + + + + + + + + + + + {% for text in text_list %} + + + + + + {% endfor %} +
Zone concernéeEnregistrement
{{ text.zone }}{{ text.dns_entry }} + {% if is_infra %} + {% include 'buttons/edit.html' with href='machines:edit-text' id=text.id %} + {% endif %} + {% include 'buttons/history.html' with href='machines:history' name='text' id=text.id %} +
+ + diff --git a/machines/templates/machines/index_extension.html b/machines/templates/machines/index_extension.html index dc3fabab..6c0bb6a9 100644 --- a/machines/templates/machines/index_extension.html +++ b/machines/templates/machines/index_extension.html @@ -47,6 +47,12 @@ with this program; if not, write to the Free Software Foundation, Inc., Supprimer un enregistrement NS {% endif %} {% include "machines/aff_ns.html" with ns_list=ns_list %} +

Liste des enregistrements Text

+ {% if is_infra %} + Ajouter un enregistrement MX + Supprimer un enregistrement MX + {% endif %} + {% include "machines/aff_text.html" with text_list=text_list %}


diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index 25c108cb..9157de08 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -36,7 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., - Extensions (zones) + Extensions et zones diff --git a/machines/urls.py b/machines/urls.py index 07ad6129..3f7e0ff3 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -44,6 +44,9 @@ urlpatterns = [ url(r'^add_mx/$', views.add_mx, name='add-mx'), url(r'^edit_mx/(?P[0-9]+)$', views.edit_mx, name='edit-mx'), url(r'^del_mx/$', views.del_mx, name='del-mx'), + url(r'^add_text/$', views.add_text, name='add-text'), + url(r'^edit_text/(?P[0-9]+)$', views.edit_text, name='edit-text'), + url(r'^del_text/$', views.del_text, name='del-text'), url(r'^add_ns/$', views.add_ns, name='add-ns'), url(r'^edit_ns/(?P[0-9]+)$', views.edit_ns, name='edit-ns'), url(r'^del_ns/$', views.del_ns, name='del-ns'), @@ -66,6 +69,7 @@ urlpatterns = [ url(r'^history/(?Pextension)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pmx)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pns)/(?P[0-9]+)$', views.history, name='history'), + url(r'^history/(?Ptext)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Piptype)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Palias)/(?P[0-9]+)$', views.history, name='history'), url(r'^history/(?Pvlan)/(?P[0-9]+)$', views.history, name='history'), @@ -78,6 +82,7 @@ urlpatterns = [ url(r'^rest/corresp/$', views.corresp, name='corresp'), url(r'^rest/mx/$', views.mx, name='mx'), url(r'^rest/ns/$', views.ns, name='ns'), + url(r'^rest/text/$', views.text, name='text'), url(r'^rest/zones/$', views.zones, name='zones'), url(r'^rest/service_servers/$', views.service_servers, name='service-servers'), ] diff --git a/machines/views.py b/machines/views.py index fb4b7a46..df04f06e 100644 --- a/machines/views.py +++ b/machines/views.py @@ -38,14 +38,14 @@ from django.contrib.auth import authenticate, login from django.views.decorators.csrf import csrf_exempt from rest_framework.renderers import JSONRenderer -from machines.serializers import InterfaceSerializer, TypeSerializer, DomainSerializer, MxSerializer, ExtensionSerializer, ServiceServersSerializer, NsSerializer +from machines.serializers import InterfaceSerializer, TypeSerializer, DomainSerializer, TextSerializer, MxSerializer, ExtensionSerializer, ServiceServersSerializer, NsSerializer from reversion import revisions as reversion from reversion.models import Version import re from .forms import NewMachineForm, EditMachineForm, EditInterfaceForm, AddInterfaceForm, MachineTypeForm, DelMachineTypeForm, ExtensionForm, DelExtensionForm, BaseEditInterfaceForm, BaseEditMachineForm -from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm -from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan +from .forms import EditIpTypeForm, IpTypeForm, DelIpTypeForm, DomainForm, AliasForm, DelAliasForm, NsForm, DelNsForm, TextForm, DelTextForm, MxForm, DelMxForm, VlanForm, DelVlanForm, ServiceForm, DelServiceForm +from .models import IpType, Machine, Interface, IpList, MachineType, Extension, Mx, Ns, Domain, Service, Service_link, Vlan, Text from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine @@ -471,6 +471,54 @@ def del_ns(request): return redirect("/machines/index_extension") return form({'machineform': ns, 'interfaceform': None}, 'machines/machine.html', request) +@login_required +@permission_required('infra') +def add_text(request): + text = TextForm(request.POST or None) + if text.is_valid(): + with transaction.atomic(), reversion.create_revision(): + text.save() + reversion.set_user(request.user) + reversion.set_comment("Création") + messages.success(request, "Cet enregistrement text a été ajouté") + return redirect("/machines/index_extension") + return form({'machineform': text, 'interfaceform': None}, 'machines/machine.html', request) + +@login_required +@permission_required('infra') +def edit_text(request, textid): + try: + text_instance = Text.objects.get(pk=textid) + except Text.DoesNotExist: + messages.error(request, u"Entrée inexistante" ) + return redirect("/machines/index_extension/") + text = TextForm(request.POST or None, instance=text_instance) + if text.is_valid(): + with transaction.atomic(), reversion.create_revision(): + text.save() + reversion.set_user(request.user) + reversion.set_comment("Champs modifié(s) : %s" % ', '.join(field for field in text.changed_data)) + messages.success(request, "Text modifié") + return redirect("/machines/index_extension/") + return form({'machineform': text}, 'machines/machine.html', request) + +@login_required +@permission_required('infra') +def del_text(request): + text = DelTextForm(request.POST or None) + if text.is_valid(): + text_dels = text.cleaned_data['text'] + for text_del in text_dels: + try: + with transaction.atomic(), reversion.create_revision(): + text_del.delete() + reversion.set_user(request.user) + messages.success(request, "Le text a été supprimé") + except ProtectedError: + messages.error(request, "Erreur le Text suivant %s ne peut être supprimé" % text_del) + return redirect("/machines/index_extension") + return form({'machineform': text, 'interfaceform': None}, 'machines/machine.html', request) + @login_required def add_alias(request, interfaceid): try: @@ -682,7 +730,8 @@ def index_extension(request): extension_list = Extension.objects.select_related('origin').order_by('name') mx_list = Mx.objects.order_by('zone').select_related('zone').select_related('name__extension') ns_list = Ns.objects.order_by('zone').select_related('zone').select_related('ns__extension') - return render(request, 'machines/index_extension.html', {'extension_list':extension_list, 'mx_list': mx_list, 'ns_list': ns_list}) + text_list = Text.objects.all().select_related('zone') + return render(request, 'machines/index_extension.html', {'extension_list':extension_list, 'mx_list': mx_list, 'ns_list': ns_list, 'text_list' : text_list}) @login_required def index_alias(request, interfaceid): @@ -757,6 +806,12 @@ def history(request, object, id): except Mx.DoesNotExist: messages.error(request, "Mx inexistant") return redirect("/machines/") + elif object == 'text' and request.user.has_perms(('cableur',)): + try: + object_instance = Text.objects.get(pk=id) + except Text.DoesNotExist: + messages.error(request, "Text inexistant") + return redirect("/machines/") elif object == 'ns' and request.user.has_perms(('cableur',)): try: object_instance = Ns.objects.get(pk=id) @@ -834,6 +889,14 @@ def mx(request): seria = MxSerializer(mx, many=True) return JSONResponse(seria.data) +@csrf_exempt +@login_required +@permission_required('serveur') +def text(request): + text = Text.objects.all().select_related('zone') + seria = TextSerializer(text, many=True) + return JSONResponse(seria.data) + @csrf_exempt @login_required @permission_required('serveur')