From 5dab70ccee3b1b0d8c692b0d477eca8588e3ec49 Mon Sep 17 00:00:00 2001 From: Charlie Jacomme Date: Sat, 23 Jun 2018 16:39:03 +0200 Subject: [PATCH 01/13] Add machines.models.Role --- machines/admin.py | 7 ++ machines/forms.py | 35 ++++++++++ machines/models.py | 20 ++++++ machines/templates/machines/aff_role.html | 49 +++++++++++++ machines/templates/machines/index_role.html | 41 +++++++++++ machines/templates/machines/machine.html | 6 ++ machines/templates/machines/sidebar.html | 6 ++ machines/urls.py | 8 ++- machines/views.py | 77 +++++++++++++++++++++ re2o/templatetags/acl.py | 1 + 10 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 machines/templates/machines/aff_role.html create mode 100644 machines/templates/machines/index_role.html diff --git a/machines/admin.py b/machines/admin.py index 26d7a6a3..0c83e9ab 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -42,6 +42,7 @@ from .models import ( SshFp, Nas, Service, + Role, OuverturePort, Ipv6List, OuverturePortList, @@ -146,6 +147,11 @@ class ServiceAdmin(VersionAdmin): """ Admin view of a ServiceAdmin object """ list_display = ('service_type', 'min_time_regen', 'regular_time_regen') +class RoleAdmin(VersionAdmin): + """ Admin view of a RoleAdmin object """ + list_display = ('role_type') + + admin.site.register(Machine, MachineAdmin) admin.site.register(MachineType, MachineTypeAdmin) @@ -162,6 +168,7 @@ admin.site.register(IpList, IpListAdmin) admin.site.register(Interface, InterfaceAdmin) admin.site.register(Domain, DomainAdmin) admin.site.register(Service, ServiceAdmin) +admin.site.register(Role, RoleAdmin) admin.site.register(Vlan, VlanAdmin) admin.site.register(Ipv6List, Ipv6ListAdmin) admin.site.register(Nas, NasAdmin) diff --git a/machines/forms.py b/machines/forms.py index 23c2aa39..c8584d30 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -53,6 +53,7 @@ from .models import ( Txt, DName, Ns, + Role, Service, Vlan, Srv, @@ -497,6 +498,40 @@ class DelNasForm(FormRevMixin, Form): self.fields['nas'].queryset = Nas.objects.all() +class RoleForm(FormRevMixin, ModelForm): + """Ajout et edition d'un role""" + class Meta: + model = Role + fields = '__all__' + + def __init__(self, *args, **kwargs): + prefix = kwargs.pop('prefix', self.Meta.model.__name__) + super(RoleForm, self).__init__(*args, prefix=prefix, **kwargs) + self.fields['servers'].queryset = (Interface.objects.all() + .select_related( + 'domain__extension' + )) + + +class DelRoleForm(FormRevMixin, Form): + """Suppression d'un ou plusieurs service""" + role = forms.ModelMultipleChoiceField( + queryset=Role.objects.none(), + label="Roles actuels", + widget=forms.CheckboxSelectMultiple + ) + + def __init__(self, *args, **kwargs): + instances = kwargs.pop('instances', None) + super(DelRoleForm, self).__init__(*args, **kwargs) + if instances: + self.fields['role'].queryset = instances + else: + self.fields['role'].queryset = role.objects.all() + + + + class ServiceForm(FormRevMixin, ModelForm): """Ajout et edition d'une classe de service : dns, dhcp, etc""" class Meta: diff --git a/machines/models.py b/machines/models.py index 7be76e74..4b3ee891 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1441,6 +1441,26 @@ class IpList(RevMixin, AclMixin, models.Model): return self.ipv4 + +class Role(RevMixin, AclMixin, models.Model): + """ Definition d'un role (routeur principal, routeur de backkup)""" + """ Sert à la génération automatique de la conf des serveurs""" + PRETTY_NAME = "Roles des serveurs" + + role_type = models.CharField(max_length=255, unique=True) + servers = models.ManyToManyField('Interface') + + class Meta: + permissions = ( + ("view_role", "Peut voir un objet service"), + ) + + def save(self, *args, **kwargs): + super(Role, self).save(*args, **kwargs) + + def __str__(self): + return str(self.role_type) + class Service(RevMixin, AclMixin, models.Model): """ Definition d'un service (dhcp, dns, etc)""" PRETTY_NAME = "Services à générer (dhcp, dns, etc)" diff --git a/machines/templates/machines/aff_role.html b/machines/templates/machines/aff_role.html new file mode 100644 index 00000000..f914cd24 --- /dev/null +++ b/machines/templates/machines/aff_role.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 %} + +{% load acl %} + + + + + + + + + + + {% for role in role_list %} + + + + + + {% endfor %} +
Nom du roleServeurs inclus
{{ role.role_type }}{% for serv in role.servers.all %}{{ serv }}, {% endfor %} + {% can_edit role %} + {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='machines:history' name='role' id=role.id %} +
+ diff --git a/machines/templates/machines/index_role.html b/machines/templates/machines/index_role.html new file mode 100644 index 00000000..93a99577 --- /dev/null +++ b/machines/templates/machines/index_role.html @@ -0,0 +1,41 @@ +{% 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 %} +{% load acl %} + +{% block title %}Machines{% endblock %} + +{% block content %} +

Liste des roles

+ {% can_create Role %} + Ajouter un role + {% acl_end %} + Supprimer un ou plusieurs role + {% include "machines/aff_role.html" with role_list=role_list %} +
+
+{% endblock %} + diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index 7ec4212a..cd00ba0c 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -71,6 +71,8 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% if sshfpform %} {% bootstrap_form_errors sshfpform %} +{% if roleform %} + {% bootstrap_form_errors roleform %} {% endif %} {% if vlanform %} {% bootstrap_form_errors vlanform %} @@ -148,6 +150,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,

Service

{% massive_bootstrap_form serviceform 'servers' %} {% endif %} + {% if roleform %} +

Role

+ {% massive_bootstrap_form roleform 'servers' %} + {% endif %} {% if vlanform %}

Vlan

{% bootstrap_form vlanform %} diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index 5a0f975d..68031f29 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -68,6 +68,12 @@ with this program; if not, write to the Free Software Foundation, Inc., Services (dhcp, dns...) {% acl_end %} + {% can_view_all Role %} + + + Roles des serveurs + + {% acl_end %} {% can_view_all OuverturePortList %} diff --git a/machines/urls.py b/machines/urls.py index ce0a7a78..8c670308 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -21,7 +21,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """machines.urls -The defined URLs for the Cotisations app +The defined URLs for the Machines app """ from __future__ import unicode_literals @@ -125,6 +125,12 @@ urlpatterns = [ 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'^add_role/$', views.add_role, name='add-role'), + url(r'^edit_role/(?P[0-9]+)$', + views.edit_role, + name='edit-role'), + url(r'^del_role/$', views.del_role, name='del-role'), + url(r'^index_role/$', views.index_role, name='index-role'), url(r'^add_vlan/$', views.add_vlan, name='add-vlan'), url(r'^edit_vlan/(?P[0-9]+)$', views.edit_vlan, name='edit-vlan'), url(r'^del_vlan/$', views.del_vlan, name='del-vlan'), diff --git a/machines/views.py b/machines/views.py index 398b9250..134560ba 100644 --- a/machines/views.py +++ b/machines/views.py @@ -101,6 +101,8 @@ from .forms import ( DelMxForm, VlanForm, DelVlanForm, + RoleForm, + DelRoleForm, ServiceForm, DelServiceForm, SshFpForm, @@ -122,6 +124,7 @@ from .models import ( Mx, Ns, Domain, + Role, Service, Service_link, Vlan, @@ -1141,6 +1144,65 @@ def del_alias(request, interface, interfaceid): ) +@login_required +@can_create(Role) +def add_role(request): + """ View used to add a Role object """ + role = RoleForm(request.POST or None) + if role.is_valid(): + role.save() + messages.success(request, "Cet enregistrement role a été ajouté") + return redirect(reverse('machines:index-role')) + return form( + {'roleform': role, 'action_name': 'Créer'}, + 'machines/machine.html', + request + ) + + +@login_required +@can_edit(Role) +def edit_role(request, role_instance, **_kwargs): + """ View used to edit a Role object """ + role = RoleForm(request.POST or None, instance=role_instance) + if role.is_valid(): + if role.changed_data: + role.save() + messages.success(request, "Role modifié") + return redirect(reverse('machines:index-role')) + return form( + {'roleform': role, 'action_name': 'Editer'}, + 'machines/machine.html', + request + ) + + +@login_required +@can_delete_set(Role) +def del_role(request, instances): + """ View used to delete a Service object """ + role = DelRoleForm(request.POST or None, instances=instances) + if role.is_valid(): + role_dels = role.cleaned_data['role'] + for role_del in role_dels: + try: + role_del.delete() + messages.success(request, "Le role a été supprimée") + except ProtectedError: + messages.error( + request, + ("Erreur le role suivant %s ne peut être supprimé" + % role_del) + ) + return redirect(reverse('machines:index-role')) + return form( + {'roleform': role, 'action_name': 'Supprimer'}, + 'machines/machine.html', + request + ) + + + @login_required @can_create(Service) def add_service(request): @@ -1481,6 +1543,21 @@ def index_ipv6(request, interface, interfaceid): ) +@login_required +@can_view_all(Role) +def index_role(request): + """ View used to display the list of existing roles """ + role_list = (Role.objects + .prefetch_related( + 'servers__domain__extension' + ).all()) + return render( + request, + 'machines/index_role.html', + {'role_list': role_list} + ) + + @login_required @can_view_all(Service) def index_service(request): diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index 9a439f88..fe13c5ac 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -79,6 +79,7 @@ from django.contrib.contenttypes.models import ContentType register = template.Library() + def get_model(model_name): """Retrieve the model object from its name""" splitted = model_name.split('.') From b70f6fd97a6ec158969db033fffbdf107d9f9bc3 Mon Sep 17 00:00:00 2001 From: Charlie Jacomme Date: Sat, 23 Jun 2018 16:47:24 +0200 Subject: [PATCH 02/13] migration for Role --- machines/migrations/0083_role.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 machines/migrations/0083_role.py diff --git a/machines/migrations/0083_role.py b/machines/migrations/0083_role.py new file mode 100644 index 00000000..7609a5ac --- /dev/null +++ b/machines/migrations/0083_role.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-06-23 14:07 +from __future__ import unicode_literals + +from django.db import migrations, models +import re2o.mixins + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0082_auto_20180621_1524'), + ] + + operations = [ + migrations.CreateModel( + name='Role', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('role_type', models.CharField(max_length=255, unique=True)), + ('servers', models.ManyToManyField(to='machines.Interface')), + ], + options={ + 'permissions': (('view_role', 'Peut voir un objet service'),), + }, + bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model), + ), + ] From 793cf302ad168bb1e6bde93a30cd00ceeb0ad8f7 Mon Sep 17 00:00:00 2001 From: chirac Date: Sat, 23 Jun 2018 16:51:15 +0200 Subject: [PATCH 03/13] Fix bug admin --- machines/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/machines/admin.py b/machines/admin.py index 0c83e9ab..af721ff9 100644 --- a/machines/admin.py +++ b/machines/admin.py @@ -149,7 +149,7 @@ class ServiceAdmin(VersionAdmin): class RoleAdmin(VersionAdmin): """ Admin view of a RoleAdmin object """ - list_display = ('role_type') + pass From 35eb94540490a3f9b1ca5b358ec0aae7f96f5572 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Wed, 11 Jul 2018 18:49:27 +0200 Subject: [PATCH 04/13] =?UTF-8?q?Notion=20de=20role=20sp=C3=A9cifique=20po?= =?UTF-8?q?ur=20retrouver=20le=20bon=20role?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/models.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/machines/models.py b/machines/models.py index 4b3ee891..4c528c45 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1447,8 +1447,31 @@ class Role(RevMixin, AclMixin, models.Model): """ Sert à la génération automatique de la conf des serveurs""" PRETTY_NAME = "Roles des serveurs" + ROLE = ( + ('dhcp-server', 'dhcp-server'), + ('switch-conf-server', 'switch-conf-server'), + ('dns-recursif-server', 'dns-recursif-server'), + ('ntp-server', 'ntp-server'), + ('radius-server', 'radius-server'), + ('ntp-server', 'ntp-server'), + ('log-server', 'log-server'), + ('ldap-master-server', 'ldap-master-server'), + ('ldap-backup-server', 'ldap-backup-server'), + ('smtp-server', 'smtp-server'), + ('postgresql-server', 'postgresql-server'), + ('mysql-server', 'mysql-server'), + ('sql-client', 'sql-client'), + ('gateway', 'gateway'), + ) + role_type = models.CharField(max_length=255, unique=True) servers = models.ManyToManyField('Interface') + specific_role = models.CharField( + choices=ROLE, + null=True, + blank=True, + max_length=32, + ) class Meta: permissions = ( From 5dc59035f564b8b9f2d8641d9e15d25d48d8a475 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Wed, 11 Jul 2018 19:46:13 +0200 Subject: [PATCH 05/13] =?UTF-8?q?Cr=C3=A9e=20sp=C3=A9cific=20role,=20l'uti?= =?UTF-8?q?lise=20pour=20get=20l'ip=20du=20serveur=20des=20config=20switch?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/serializers.py | 44 +++++++++++++++++++ .../migrations/0094_role_specific_role.py | 20 +++++++++ machines/models.py | 13 ++++++ machines/templates/machines/aff_role.html | 2 + 4 files changed, 79 insertions(+) create mode 100644 machines/migrations/0094_role_specific_role.py diff --git a/api/serializers.py b/api/serializers.py index 398f2b19..ffb3aaba 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -622,6 +622,50 @@ class ServiceRegenSerializer(NamespacedHMSerializer): 'api_url': {'view_name': 'serviceregen-detail'} } +# Switches et ports + +class InterfaceVlanSerializer(NamespacedHMSerializer): + domain = serializers.CharField(read_only=True) + ipv4 = serializers.CharField(read_only=True) + ipv6 = Ipv6ListSerializer(read_only=True, many=True) + vlan_id = serializers.IntegerField(source='type.ip_type.vlan.vlan_id', read_only=True) + + class Meta: + model = machines.Interface + fields = ('ipv4', 'ipv6', 'domain', 'vlan_id') + +class InterfaceRoleSerializer(NamespacedHMSerializer): + interface = InterfaceVlanSerializer(source='machine.interface_set', read_only=True, many=True) + + class Meta: + model = machines.Interface + fields = ('interface',) + + +class RoleSerializer(NamespacedHMSerializer): + """Serialize `machines.models.OuverturePort` objects. + """ + servers = InterfaceRoleSerializer(read_only=True, many=True) + + class Meta: + model = machines.Role + fields = ('role_type', 'servers', 'specific_role') + + +class VlanPortSerializer(NamespacedHMSerializer): + class Meta: + model = machines.Vlan + fields = ('vlan_id', 'name') + + +class ProfilSerializer(NamespacedHMSerializer): + vlan_untagged = VlanSerializer(read_only=True) + vlan_tagged = VlanPortSerializer(read_only=True, many=True) + + class Meta: + model = topologie.PortProfile + fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged', 'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control', 'dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'ra_guard', 'loop_protect', 'vlan_untagged', 'vlan_tagged') + # LOCAL EMAILS diff --git a/machines/migrations/0094_role_specific_role.py b/machines/migrations/0094_role_specific_role.py new file mode 100644 index 00000000..73cade7b --- /dev/null +++ b/machines/migrations/0094_role_specific_role.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2018-07-11 16:49 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0093_merge_20180710_0226'), + ] + + operations = [ + migrations.AddField( + model_name='role', + name='specific_role', + field=models.CharField(blank=True, choices=[('dhcp-server', 'dhcp-server'), ('switch-conf-server', 'switch-conf-server'), ('dns-recursif-server', 'dns-recursif-server'), ('ntp-server', 'ntp-server'), ('radius-server', 'radius-server'), ('ntp-server', 'ntp-server'), ('log-server', 'log-server'), ('ldap-master-server', 'ldap-master-server'), ('ldap-backup-server', 'ldap-backup-server'), ('smtp-server', 'smtp-server'), ('postgresql-server', 'postgresql-server'), ('mysql-server', 'mysql-server'), ('sql-client', 'sql-client'), ('gateway', 'gateway')], max_length=32, null=True), + ), + ] diff --git a/machines/models.py b/machines/models.py index 4c528c45..2f401301 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1478,6 +1478,19 @@ class Role(RevMixin, AclMixin, models.Model): ("view_role", "Peut voir un objet service"), ) + @classmethod + def get_instance(cls, machineid, *_args, **_kwargs): + """Get the Machine instance with machineid. + :param userid: The id + :return: The user + """ + return cls.objects.get(pk=machineid) + + @classmethod + def interface_for_roletype(cls, roletype): + """Return interfaces for a roletype""" + return Interface.objects.filter(role=cls.objects.filter(specific_role=roletype)) + def save(self, *args, **kwargs): super(Role, self).save(*args, **kwargs) diff --git a/machines/templates/machines/aff_role.html b/machines/templates/machines/aff_role.html index f914cd24..691cc0c2 100644 --- a/machines/templates/machines/aff_role.html +++ b/machines/templates/machines/aff_role.html @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Nom du role + Role spécifique Serveurs inclus @@ -36,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% for role in role_list %} {{ role.role_type }} + {{ role.specific_role }} {% for serv in role.servers.all %}{{ serv }}, {% endfor %} {% can_edit role %} From ed91cdcfe507aa6579ce34f4f54c3909f3c69c33 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Thu, 12 Jul 2018 16:24:45 +0200 Subject: [PATCH 06/13] Recolle les fixations ensemble --- CHANGELOG.md | 8 ++++++++ machines/migrations/{0083_role.py => 0084_role.py} | 2 +- ...4_role_specific_role.py => 0085_role_specific_role.py} | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) rename machines/migrations/{0083_role.py => 0084_role.py} (93%) rename machines/migrations/{0094_role_specific_role.py => 0085_role_specific_role.py} (94%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b9020e1..dcf03168 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,3 +120,11 @@ Don't forget to run migrations, several settings previously in the `preferences` in their own Payment models. To have a closer look on how the payments works, please go to the wiki. + +## MR xxx: Add role models + +Adds the Role model. +You need to ensure that your database character set is utf-8. +```sql +ALTER DATABASE re2o CHARACTER SET utf8; +``` diff --git a/machines/migrations/0083_role.py b/machines/migrations/0084_role.py similarity index 93% rename from machines/migrations/0083_role.py rename to machines/migrations/0084_role.py index 7609a5ac..bb113813 100644 --- a/machines/migrations/0083_role.py +++ b/machines/migrations/0084_role.py @@ -9,7 +9,7 @@ import re2o.mixins class Migration(migrations.Migration): dependencies = [ - ('machines', '0082_auto_20180621_1524'), + ('machines', '0083_remove_duplicate_rights'), ] operations = [ diff --git a/machines/migrations/0094_role_specific_role.py b/machines/migrations/0085_role_specific_role.py similarity index 94% rename from machines/migrations/0094_role_specific_role.py rename to machines/migrations/0085_role_specific_role.py index 73cade7b..d861f45b 100644 --- a/machines/migrations/0094_role_specific_role.py +++ b/machines/migrations/0085_role_specific_role.py @@ -8,7 +8,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('machines', '0093_merge_20180710_0226'), + ('machines', '0084_role'), ] operations = [ From 0b86dc1ec498d22f776542401fe1b9b0d8778bce Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 17 Jul 2018 21:26:42 +0200 Subject: [PATCH 07/13] TODO : offrir des cours d'anglais au cr@ns. --- CHANGELOG.md | 2 +- machines/forms.py | 11 ++- machines/models.py | 97 ++++++++++++----------- machines/templates/machines/aff_role.html | 46 ++++++----- machines/views.py | 70 ++++++++-------- 5 files changed, 118 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcf03168..f390ba09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,7 +121,7 @@ in their own Payment models. To have a closer look on how the payments works, please go to the wiki. -## MR xxx: Add role models +## MR 182: Add role models Adds the Role model. You need to ensure that your database character set is utf-8. diff --git a/machines/forms.py b/machines/forms.py index c8584d30..ecffcc71 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -37,6 +37,7 @@ from __future__ import unicode_literals from django.forms import ModelForm, Form from django import forms +from django.utils.translation import ugettext_lazy as _l from re2o.field_permissions import FieldPermissionFormMixin from re2o.mixins import FormRevMixin @@ -499,7 +500,7 @@ class DelNasForm(FormRevMixin, Form): class RoleForm(FormRevMixin, ModelForm): - """Ajout et edition d'un role""" + """Add and edit role.""" class Meta: model = Role fields = '__all__' @@ -514,10 +515,10 @@ class RoleForm(FormRevMixin, ModelForm): class DelRoleForm(FormRevMixin, Form): - """Suppression d'un ou plusieurs service""" + """Deletion of one or several roles.""" role = forms.ModelMultipleChoiceField( queryset=Role.objects.none(), - label="Roles actuels", + label=_l("Current roles"), widget=forms.CheckboxSelectMultiple ) @@ -527,9 +528,7 @@ class DelRoleForm(FormRevMixin, Form): if instances: self.fields['role'].queryset = instances else: - self.fields['role'].queryset = role.objects.all() - - + self.fields['role'].queryset = Role.objects.all() class ServiceForm(FormRevMixin, ModelForm): diff --git a/machines/models.py b/machines/models.py index 2f401301..6ce84adb 100644 --- a/machines/models.py +++ b/machines/models.py @@ -42,6 +42,7 @@ from django.forms import ValidationError from django.utils.functional import cached_property from django.utils import timezone from django.core.validators import MaxValueValidator +from django.utils.translation import ugettext_lazy as _l from macaddress.fields import MACAddressField @@ -158,7 +159,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -176,7 +177,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -338,10 +339,10 @@ class IpType(RevMixin, AclMixin, models.Model): return else: for ipv6 in Ipv6List.objects.filter( - interface__in=Interface.objects.filter( - type__in=MachineType.objects.filter(ip_type=self) - ) - ): + interface__in=Interface.objects.filter( + type__in=MachineType.objects.filter(ip_type=self) + ) + ): ipv6.check_and_replace_prefix(prefix=self.prefix_v6) def clean(self): @@ -713,7 +714,7 @@ class Srv(RevMixin, AclMixin, models.Model): choices=( (TCP, 'TCP'), (UDP, 'UDP'), - ), + ), default=TCP, ) extension = models.ForeignKey('Extension', on_delete=models.PROTECT) @@ -1047,7 +1048,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -1064,7 +1065,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -1165,7 +1166,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -1182,7 +1183,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): user_request, *args, **kwargs - )[0]): + )[0]): return False, (u"Vous ne pouvez pas éditer une machine " "d'un autre user que vous sans droit") return True, None @@ -1358,11 +1359,11 @@ class Domain(RevMixin, AclMixin, models.Model): return False, (u"Vous ne pouvez pas ajouter un alias à une " "machine d'un autre user que vous sans droit") if Domain.objects.filter( - cname__in=Domain.objects.filter( - interface_parent__in=(interface.machine.user - .user_interfaces()) - ) - ).count() >= max_lambdauser_aliases: + cname__in=Domain.objects.filter( + interface_parent__in=(interface.machine.user + .user_interfaces()) + ) + ).count() >= max_lambdauser_aliases: return False, (u"Vous avez atteint le maximum d'alias " "autorisés que vous pouvez créer vous même " "(%s) " % max_lambdauser_aliases) @@ -1441,27 +1442,25 @@ class IpList(RevMixin, AclMixin, models.Model): return self.ipv4 - class Role(RevMixin, AclMixin, models.Model): - """ Definition d'un role (routeur principal, routeur de backkup)""" - """ Sert à la génération automatique de la conf des serveurs""" - PRETTY_NAME = "Roles des serveurs" + """Define the role of a machine. + Allow automated generation of the server configuration. + """ ROLE = ( - ('dhcp-server', 'dhcp-server'), - ('switch-conf-server', 'switch-conf-server'), - ('dns-recursif-server', 'dns-recursif-server'), - ('ntp-server', 'ntp-server'), - ('radius-server', 'radius-server'), - ('ntp-server', 'ntp-server'), - ('log-server', 'log-server'), - ('ldap-master-server', 'ldap-master-server'), - ('ldap-backup-server', 'ldap-backup-server'), - ('smtp-server', 'smtp-server'), - ('postgresql-server', 'postgresql-server'), - ('mysql-server', 'mysql-server'), - ('sql-client', 'sql-client'), - ('gateway', 'gateway'), + ('dhcp-server', _l('DHCP server')), + ('switch-conf-server', _l('Switches configuration server')), + ('dns-recursif-server', _l('Recursive DNS server')), + ('ntp-server', _l('NTP server')), + ('radius-server', _l('Radius server')), + ('log-server', _l('Log server')), + ('ldap-master-server', _l('LDAP master server')), + ('ldap-backup-server', _l('LDAP backup server')), + ('smtp-server', _l('SMTP server')), + ('postgresql-server', _l('postgreSQL server')), + ('mysql-server', _l('mySQL server')), + ('sql-client', _l('SQL client')), + ('gateway', _l('Gatewaw')), ) role_type = models.CharField(max_length=255, unique=True) @@ -1475,21 +1474,28 @@ class Role(RevMixin, AclMixin, models.Model): class Meta: permissions = ( - ("view_role", "Peut voir un objet service"), + ("view_role", _l("Can view a role.")), ) + verbose_name = _l("Server role") @classmethod - def get_instance(cls, machineid, *_args, **_kwargs): - """Get the Machine instance with machineid. - :param userid: The id - :return: The user + def get_instance(cls, roleid, *_args, **_kwargs): + """Get the Role instance with roleid. + + Args: + roleid: The id + + Returns: + The role. """ - return cls.objects.get(pk=machineid) + return cls.objects.get(pk=roleid) @classmethod def interface_for_roletype(cls, roletype): """Return interfaces for a roletype""" - return Interface.objects.filter(role=cls.objects.filter(specific_role=roletype)) + return Interface.objects.filter( + role=cls.objects.filter(specific_role=roletype) + ) def save(self, *args, **kwargs): super(Role, self).save(*args, **kwargs) @@ -1497,6 +1503,7 @@ class Role(RevMixin, AclMixin, models.Model): def __str__(self): return str(self.role_type) + class Service(RevMixin, AclMixin, models.Model): """ Definition d'un service (dhcp, dns, etc)""" PRETTY_NAME = "Services à générer (dhcp, dns, etc)" @@ -1527,8 +1534,8 @@ class Service(RevMixin, AclMixin, models.Model): """ Django ne peut créer lui meme les relations manytomany avec table intermediaire explicite""" for serv in servers.exclude( - pk__in=Interface.objects.filter(service=self) - ): + pk__in=Interface.objects.filter(service=self) + ): link = Service_link(service=self, server=serv) link.save() Service_link.objects.filter(service=self).exclude(server__in=servers)\ @@ -1686,7 +1693,7 @@ class OuverturePort(RevMixin, AclMixin, models.Model): choices=( (TCP, 'TCP'), (UDP, 'UDP'), - ), + ), default=TCP, ) io = models.CharField( @@ -1694,7 +1701,7 @@ class OuverturePort(RevMixin, AclMixin, models.Model): choices=( (IN, 'IN'), (OUT, 'OUT'), - ), + ), default=OUT, ) diff --git a/machines/templates/machines/aff_role.html b/machines/templates/machines/aff_role.html index 691cc0c2..f83a4adb 100644 --- a/machines/templates/machines/aff_role.html +++ b/machines/templates/machines/aff_role.html @@ -23,29 +23,31 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} +{% load i18n %} - - - - - - - - - - - {% for role in role_list %} + +
Nom du roleRole spécifiqueServeurs inclus
+ - - - - + + + + + - {% endfor %} -
{{ role.role_type }}{{ role.specific_role }}{% for serv in role.servers.all %}{{ serv }}, {% endfor %} - {% can_edit role %} - {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} - {% acl_end %} - {% include 'buttons/history.html' with href='machines:history' name='role' id=role.id %} - {% trans "Role name" %}{% trans "Specific role" %}{% trans "Servers" %}
+ + {% for role in role_list %} + + {{ role.role_type }} + {{ role.specific_role }} + {% for serv in role.servers.all %}{{ serv }}, {% endfor %} + + {% can_edit role %} + {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='machines:history' name='role' id=role.id %} + + + {% endfor %} + diff --git a/machines/views.py b/machines/views.py index 134560ba..975cac08 100644 --- a/machines/views.py +++ b/machines/views.py @@ -40,6 +40,7 @@ from django.contrib.auth.decorators import login_required, permission_required from django.db.models import ProtectedError, F from django.forms import modelformset_factory from django.views.decorators.csrf import csrf_exempt +from django.utils.translation import ugettext as _ from rest_framework.renderers import JSONRenderer @@ -181,14 +182,14 @@ def generate_ipv4_engine(is_type_tt): """ return ( 'new Bloodhound( {{' - 'datumTokenizer: Bloodhound.tokenizers.obj.whitespace( "value" ),' - 'queryTokenizer: Bloodhound.tokenizers.whitespace,' - 'local: choices_ipv4[ $( "#{type_id}" ).val() ],' - 'identify: function( obj ) {{ return obj.key; }}' + 'datumTokenizer: Bloodhound.tokenizers.obj.whitespace( "value" ),' + 'queryTokenizer: Bloodhound.tokenizers.whitespace,' + 'local: choices_ipv4[ $( "#{type_id}" ).val() ],' + 'identify: function( obj ) {{ return obj.key; }}' '}} )' - ).format( - type_id=f_type_id(is_type_tt) - ) + ).format( + type_id=f_type_id(is_type_tt) + ) def generate_ipv4_match_func(is_type_tt): @@ -196,17 +197,17 @@ def generate_ipv4_match_func(is_type_tt): """ return ( 'function(q, sync) {{' - 'if (q === "") {{' - 'var first = choices_ipv4[$("#{type_id}").val()].slice(0, 5);' - 'first = first.map( function (obj) {{ return obj.key; }} );' - 'sync(engine_ipv4.get(first));' - '}} else {{' - 'engine_ipv4.search(q, sync);' - '}}' + 'if (q === "") {{' + 'var first = choices_ipv4[$("#{type_id}").val()].slice(0, 5);' + 'first = first.map( function (obj) {{ return obj.key; }} );' + 'sync(engine_ipv4.get(first));' + '}} else {{' + 'engine_ipv4.search(q, sync);' '}}' - ).format( - type_id=f_type_id(is_type_tt) - ) + '}}' + ).format( + type_id=f_type_id(is_type_tt) + ) def generate_ipv4_mbf_param(form_obj, is_type_tt): @@ -1168,10 +1169,10 @@ def edit_role(request, role_instance, **_kwargs): if role.is_valid(): if role.changed_data: role.save() - messages.success(request, "Role modifié") + messages.success(request, _("Role updated")) return redirect(reverse('machines:index-role')) return form( - {'roleform': role, 'action_name': 'Editer'}, + {'roleform': role, 'action_name': _('Edit')}, 'machines/machine.html', request ) @@ -1187,22 +1188,22 @@ def del_role(request, instances): for role_del in role_dels: try: role_del.delete() - messages.success(request, "Le role a été supprimée") + messages.success(request, _("The role has been deleted.")) except ProtectedError: messages.error( request, - ("Erreur le role suivant %s ne peut être supprimé" - % role_del) + (_("Error: The following role cannot be deleted: %(role)") + % {'role': role_del} + ) ) return redirect(reverse('machines:index-role')) return form( - {'roleform': role, 'action_name': 'Supprimer'}, + {'roleform': role, 'action_name': _('Delete')}, 'machines/machine.html', request ) - @login_required @can_create(Service) def add_service(request): @@ -1548,9 +1549,9 @@ def index_ipv6(request, interface, interfaceid): def index_role(request): """ View used to display the list of existing roles """ role_list = (Role.objects - .prefetch_related( - 'servers__domain__extension' - ).all()) + .prefetch_related( + 'servers__domain__extension' + ).all()) return render( request, 'machines/index_role.html', @@ -1647,12 +1648,12 @@ def add_portlist(request): """ View used to add a port policy """ port_list = EditOuverturePortListForm(request.POST or None) port_formset = modelformset_factory( - OuverturePort, - fields=('begin', 'end', 'protocole', 'io'), - extra=0, - can_delete=True, - min_num=1, - validate_min=True, + OuverturePort, + fields=('begin', 'end', 'protocole', 'io'), + extra=0, + can_delete=True, + min_num=1, + validate_min=True, )(request.POST or None, queryset=OuverturePort.objects.none()) if port_list.is_valid() and port_formset.is_valid(): pl = port_list.save() @@ -1699,11 +1700,12 @@ def configure_ports(request, interface_instance, **_kwargs): ) -## Framework Rest +# Framework Rest class JSONResponse(HttpResponse): """ Class to build a JSON response. Used for API """ + def __init__(self, data, **kwargs): content = JSONRenderer().render(data) kwargs['content_type'] = 'application/json' From d7af7d64a20e0c6ad3320fc201bab525bb7dac09 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 17 Jul 2018 21:42:03 +0200 Subject: [PATCH 08/13] Une migration de Role pour les gouverner toutes. --- machines/migrations/0084_role.py | 5 ++--- .../migrations/0085_role_specific_role.py | 20 ------------------- 2 files changed, 2 insertions(+), 23 deletions(-) delete mode 100644 machines/migrations/0085_role_specific_role.py diff --git a/machines/migrations/0084_role.py b/machines/migrations/0084_role.py index bb113813..49343809 100644 --- a/machines/migrations/0084_role.py +++ b/machines/migrations/0084_role.py @@ -19,10 +19,9 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('role_type', models.CharField(max_length=255, unique=True)), ('servers', models.ManyToManyField(to='machines.Interface')), + ('specific_role', models.CharField(blank=True, choices=[('dhcp-server', 'DHCP server'), ('switch-conf-server', 'Switches configuration server'), ('dns-recursif-server', 'Recursive DNS server'), ('ntp-server', 'NTP server'), ('radius-server', 'Radius server'), ('log-server', 'Log server'), ('ldap-master-server', 'LDAP master server'), ('ldap-backup-server', 'LDAP backup server'), ('smtp-server', 'SMTP server'), ('postgresql-server', 'postgreSQL server'), ('mysql-server', 'mySQL server'), ('sql-client', 'SQL client'), ('gateway', 'Gatewaw')], max_length=32, null=True)) ], - options={ - 'permissions': (('view_role', 'Peut voir un objet service'),), - }, + options={'permissions': (('view_role', 'Can view a role.'),), 'verbose_name': 'Server role'}, bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model), ), ] diff --git a/machines/migrations/0085_role_specific_role.py b/machines/migrations/0085_role_specific_role.py deleted file mode 100644 index d861f45b..00000000 --- a/machines/migrations/0085_role_specific_role.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2018-07-11 16:49 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('machines', '0084_role'), - ] - - operations = [ - migrations.AddField( - model_name='role', - name='specific_role', - field=models.CharField(blank=True, choices=[('dhcp-server', 'dhcp-server'), ('switch-conf-server', 'switch-conf-server'), ('dns-recursif-server', 'dns-recursif-server'), ('ntp-server', 'ntp-server'), ('radius-server', 'radius-server'), ('ntp-server', 'ntp-server'), ('log-server', 'log-server'), ('ldap-master-server', 'ldap-master-server'), ('ldap-backup-server', 'ldap-backup-server'), ('smtp-server', 'smtp-server'), ('postgresql-server', 'postgresql-server'), ('mysql-server', 'mysql-server'), ('sql-client', 'sql-client'), ('gateway', 'gateway')], max_length=32, null=True), - ), - ] From 5e5bd89885f40114b8a8badbba601780ef4eb06a Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 17 Jul 2018 21:47:20 +0200 Subject: [PATCH 09/13] =?UTF-8?q?Anglais=20=C3=A9pisode=202=20:=20L'attaqu?= =?UTF-8?q?e=20des=20templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/templates/machines/index_role.html | 7 ++++--- machines/templates/machines/sidebar.html | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/machines/templates/machines/index_role.html b/machines/templates/machines/index_role.html index 93a99577..86c36a09 100644 --- a/machines/templates/machines/index_role.html +++ b/machines/templates/machines/index_role.html @@ -25,15 +25,16 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} {% load acl %} +{% load i18n %} {% block title %}Machines{% endblock %} {% block content %} -

Liste des roles

+

{% trans "Roles list" %}

{% can_create Role %} -
Ajouter un role + {% trans "Add role"%} {% acl_end %} - Supprimer un ou plusieurs role + {% trans "Delete one or several roles" %} {% include "machines/aff_role.html" with role_list=role_list %}

diff --git a/machines/templates/machines/sidebar.html b/machines/templates/machines/sidebar.html index 68031f29..75badb6b 100644 --- a/machines/templates/machines/sidebar.html +++ b/machines/templates/machines/sidebar.html @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endcomment %} {% load acl %} +{% load i18n %} {% block sidebar %} {% can_view_all Machine %} @@ -71,7 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_view_all Role %} - Roles des serveurs + {% trans "Server roles" %} {% acl_end %} {% can_view_all OuverturePortList %} From 7166318e19048cbf6b38c7e82ec2b7c5827338a9 Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Thu, 12 Jul 2018 00:11:55 +0200 Subject: [PATCH 10/13] Repare le get_instance de role --- api/serializers.py | 7 ++++++- machines/models.py | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/api/serializers.py b/api/serializers.py index ffb3aaba..db3f1b7b 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -338,10 +338,15 @@ class OptionalMachineSerializer(NamespacedHMSerializer): class OptionalTopologieSerializer(NamespacedHMSerializer): """Serialize `preferences.models.OptionalTopologie` objects. """ + switchs_management_interface_ip= serializers.CharField(read_only=True) + class Meta: model = preferences.OptionalTopologie fields = ('radius_general_policy', 'vlan_decision_ok', - 'vlan_decision_nok') + 'vlan_decision_nok', 'switchs_ip_type', 'switchs_web_management', + 'switchs_web_management_ssl', 'switchs_rest_management', + 'switchs_management_utils', 'switchs_management_interface_ip', + 'provision_switchs_enabled') class GeneralOptionSerializer(NamespacedHMSerializer): diff --git a/machines/models.py b/machines/models.py index 6ce84adb..e981bf10 100644 --- a/machines/models.py +++ b/machines/models.py @@ -1497,6 +1497,13 @@ class Role(RevMixin, AclMixin, models.Model): role=cls.objects.filter(specific_role=roletype) ) + @classmethod + def all_interfaces_for_roletype(cls, roletype): + """Return all interfaces for a roletype""" + return Interface.objects.filter( + machine__interface__role=cls.objects.filter(specific_role=roletype) + ) + def save(self, *args, **kwargs): super(Role, self).save(*args, **kwargs) From 4679bbe604b69b4984e815bc57c5ebeeae0e9705 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Tue, 17 Jul 2018 22:27:58 +0200 Subject: [PATCH 11/13] Retire des modifications qui viendrons avec les switchs. --- api/serializers.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/api/serializers.py b/api/serializers.py index db3f1b7b..cdcf41f7 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -338,15 +338,11 @@ class OptionalMachineSerializer(NamespacedHMSerializer): class OptionalTopologieSerializer(NamespacedHMSerializer): """Serialize `preferences.models.OptionalTopologie` objects. """ - switchs_management_interface_ip= serializers.CharField(read_only=True) class Meta: model = preferences.OptionalTopologie fields = ('radius_general_policy', 'vlan_decision_ok', - 'vlan_decision_nok', 'switchs_ip_type', 'switchs_web_management', - 'switchs_web_management_ssl', 'switchs_rest_management', - 'switchs_management_utils', 'switchs_management_interface_ip', - 'provision_switchs_enabled') + 'vlan_decision_nok') class GeneralOptionSerializer(NamespacedHMSerializer): From 6202ddd0fac9f3906a956f1a8618e11c6aeb50a8 Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 29 Jul 2018 17:21:58 +0200 Subject: [PATCH 12/13] =?UTF-8?q?D=C3=A9plac=C3=A9=20dans=20une=20MR=20ult?= =?UTF-8?q?=C3=A9rieure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/serializers.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/api/serializers.py b/api/serializers.py index cdcf41f7..839a1047 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -623,41 +623,6 @@ class ServiceRegenSerializer(NamespacedHMSerializer): 'api_url': {'view_name': 'serviceregen-detail'} } -# Switches et ports - -class InterfaceVlanSerializer(NamespacedHMSerializer): - domain = serializers.CharField(read_only=True) - ipv4 = serializers.CharField(read_only=True) - ipv6 = Ipv6ListSerializer(read_only=True, many=True) - vlan_id = serializers.IntegerField(source='type.ip_type.vlan.vlan_id', read_only=True) - - class Meta: - model = machines.Interface - fields = ('ipv4', 'ipv6', 'domain', 'vlan_id') - -class InterfaceRoleSerializer(NamespacedHMSerializer): - interface = InterfaceVlanSerializer(source='machine.interface_set', read_only=True, many=True) - - class Meta: - model = machines.Interface - fields = ('interface',) - - -class RoleSerializer(NamespacedHMSerializer): - """Serialize `machines.models.OuverturePort` objects. - """ - servers = InterfaceRoleSerializer(read_only=True, many=True) - - class Meta: - model = machines.Role - fields = ('role_type', 'servers', 'specific_role') - - -class VlanPortSerializer(NamespacedHMSerializer): - class Meta: - model = machines.Vlan - fields = ('vlan_id', 'name') - class ProfilSerializer(NamespacedHMSerializer): vlan_untagged = VlanSerializer(read_only=True) From a7ea8a151881869506f6231ae5adfecb56af0da0 Mon Sep 17 00:00:00 2001 From: Hugo LEVY-FALK Date: Fri, 3 Aug 2018 00:21:23 +0200 Subject: [PATCH 13/13] =?UTF-8?q?R=C3=A9pare=20de=20petits=20soucis=20de?= =?UTF-8?q?=20templates=20+=20problemes=20de=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/serializers.py | 9 --------- machines/migrations/{0084_role.py => 0086_role.py} | 2 +- machines/templates/machines/aff_role.html | 3 ++- machines/templates/machines/machine.html | 1 + 4 files changed, 4 insertions(+), 11 deletions(-) rename machines/migrations/{0084_role.py => 0086_role.py} (96%) diff --git a/api/serializers.py b/api/serializers.py index 839a1047..3a5f7f90 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -624,15 +624,6 @@ class ServiceRegenSerializer(NamespacedHMSerializer): } -class ProfilSerializer(NamespacedHMSerializer): - vlan_untagged = VlanSerializer(read_only=True) - vlan_tagged = VlanPortSerializer(read_only=True, many=True) - - class Meta: - model = topologie.PortProfile - fields = ('name', 'profil_default', 'vlan_untagged', 'vlan_tagged', 'radius_type', 'radius_mode', 'speed', 'mac_limit', 'flow_control', 'dhcp_snooping', 'dhcpv6_snooping', 'arp_protect', 'ra_guard', 'loop_protect', 'vlan_untagged', 'vlan_tagged') - - # LOCAL EMAILS diff --git a/machines/migrations/0084_role.py b/machines/migrations/0086_role.py similarity index 96% rename from machines/migrations/0084_role.py rename to machines/migrations/0086_role.py index 49343809..a23de26f 100644 --- a/machines/migrations/0084_role.py +++ b/machines/migrations/0086_role.py @@ -9,7 +9,7 @@ import re2o.mixins class Migration(migrations.Migration): dependencies = [ - ('machines', '0083_remove_duplicate_rights'), + ('machines', '0085_sshfingerprint'), ] operations = [ diff --git a/machines/templates/machines/aff_role.html b/machines/templates/machines/aff_role.html index f83a4adb..519e8fd6 100644 --- a/machines/templates/machines/aff_role.html +++ b/machines/templates/machines/aff_role.html @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load acl %} {% load i18n %} +{% load logs_extra %} @@ -45,7 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% can_edit role %} {% include 'buttons/edit.html' with href='machines:edit-role' id=role.id %} {% acl_end %} - {% include 'buttons/history.html' with href='machines:history' name='role' id=role.id %} + {% history_button role %} {% endfor %} diff --git a/machines/templates/machines/machine.html b/machines/templates/machines/machine.html index cd00ba0c..d6c0f522 100644 --- a/machines/templates/machines/machine.html +++ b/machines/templates/machines/machine.html @@ -71,6 +71,7 @@ with this program; if not, write to the Free Software Foundation, Inc., {% endif %} {% if sshfpform %} {% bootstrap_form_errors sshfpform %} +{% endif %} {% if roleform %} {% bootstrap_form_errors roleform %} {% endif %}