From 7e1e207b9951a0635bcf922d4f8180c81b49b8fd Mon Sep 17 00:00:00 2001 From: Gabriel Detraz Date: Tue, 8 Aug 2017 19:40:30 +0200 Subject: [PATCH] =?UTF-8?q?Final=20commit=20pour=20la=20reconfiguration=20?= =?UTF-8?q?automatique=20centralis=C3=A9e=20des=20services?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0046_auto_20170808_1423.py | 21 +++++++++++++++ machines/models.py | 26 ++++++++++++++++--- machines/serializers.py | 19 +++++++++++++- machines/urls.py | 2 ++ machines/views.py | 19 +++++++++++++- 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 machines/migrations/0046_auto_20170808_1423.py diff --git a/machines/migrations/0046_auto_20170808_1423.py b/machines/migrations/0046_auto_20170808_1423.py new file mode 100644 index 00000000..b7ffbced --- /dev/null +++ b/machines/migrations/0046_auto_20170808_1423.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-08-08 12:23 +from __future__ import unicode_literals + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('machines', '0045_auto_20170808_0348'), + ] + + operations = [ + migrations.AlterField( + model_name='service', + name='time_regen', + field=models.DurationField(default=datetime.timedelta(0, 60)), + ), + ] diff --git a/machines/models.py b/machines/models.py index 44f0163f..69b6f825 100644 --- a/machines/models.py +++ b/machines/models.py @@ -31,9 +31,11 @@ from netaddr import mac_bare, EUI, IPSet, IPNetwork from django.core.validators import MinValueValidator,MaxValueValidator import re from reversion import revisions as reversion +from datetime import timedelta from re2o.settings import MAIN_EXTENSION + class Machine(models.Model): """ Class définissant une machine, object parent user, objets fils interfaces""" PRETTY_NAME = "Machine" @@ -273,15 +275,17 @@ class IpList(models.Model): 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() + time_regen = models.DurationField(default=timedelta(minutes=1)) servers = models.ManyToManyField('Interface', through='Service_link') def ask_regen(self): - for serv in Service_link.objects.filter(service=self): + """ Marque à True la demande de régénération pour un service x """ + for serv in Service_link.objects.filter(service=self).exclude(asked_regen=True): serv.asked_regen = True serv.save() def process_link(self, servers): + """ 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)): link = Service_link(service=self, server=serv) link.save() @@ -295,6 +299,12 @@ class Service(models.Model): def __str__(self): return str(self.service_type) +def regen(service): + """ Fonction externe pour régérération d'un service, prend un objet service en arg""" + obj, created = Service.objects.get_or_create(service_type=service) + obj.ask_regen() + return + class Service_link(models.Model): """ Definition du lien entre serveurs et services""" service = models.ForeignKey('Service', on_delete=models.CASCADE) @@ -302,9 +312,15 @@ class Service_link(models.Model): last_regen = models.DateTimeField(auto_now_add=True) asked_regen = models.BooleanField(default=False) + def done_regen(self): + """ Appellé lorsqu'un serveur a regénéré son service""" + self.last_regen = timezone.now() + self.asked_regen = False + self.save() def need_regen(self): - if self.asked_regen and (self.last_regen + self.service.time_regen) > timezone.now(): + """ Décide si le temps minimal écoulé est suffisant pour provoquer une régénération de service""" + if self.asked_regen and (self.last_regen + self.service.time_regen) < timezone.now(): return True else: return False @@ -316,6 +332,8 @@ class Service_link(models.Model): def machine_post_save(sender, **kwargs): user = kwargs['instance'].user user.ldap_sync(base=False, access_refresh=False, mac_refresh=True) + regen('dhcp') + regen('dns') @receiver(post_delete, sender=Machine) def machine_post_delete(sender, **kwargs): @@ -328,6 +346,8 @@ def interface_post_save(sender, **kwargs): interface = kwargs['instance'] user = interface.machine.user user.ldap_sync(base=False, access_refresh=False, mac_refresh=True) + regen('dhcp') + regen('dns') @receiver(post_delete, sender=Interface) def interface_post_delete(sender, **kwargs): diff --git a/machines/serializers.py b/machines/serializers.py index f21f1d41..2a29a6bc 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, Ns +from machines.models import Interface, IpType, Extension, IpList, MachineType, Domain, Mx, Service_link, Ns class IpTypeField(serializers.RelatedField): def to_representation(self, value): @@ -118,3 +118,20 @@ class DomainSerializer(serializers.ModelSerializer): def get_cname_name(self, obj): return str(obj.cname) +class ServiceServersSerializer(serializers.ModelSerializer): + server = serializers.SerializerMethodField('get_server_name') + service = serializers.SerializerMethodField('get_service_name') + need_regen = serializers.SerializerMethodField('get_regen_status') + + class Meta: + model = Service_link + fields = ('server', 'service', 'need_regen') + + def get_server_name(self, obj): + return str(obj.server.domain.name) + + def get_service_name(self, obj): + return str(obj.service) + + def get_regen_status(self, obj): + return obj.need_regen() diff --git a/machines/urls.py b/machines/urls.py index 1b352139..2c9d7e4d 100644 --- a/machines/urls.py +++ b/machines/urls.py @@ -68,10 +68,12 @@ urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^rest/mac-ip/$', views.mac_ip, name='mac-ip'), url(r'^rest/login/$', views.login_user, name='login'), + url(r'^rest/regen-achieved/$', views.regen_achieved, name='regen-achieved'), url(r'^rest/mac-ip-dns/$', views.mac_ip_dns, name='mac-ip-dns'), url(r'^rest/alias/$', views.alias, name='alias'), 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/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 c8d66f43..f3a77d9e 100644 --- a/machines/views.py +++ b/machines/views.py @@ -38,7 +38,7 @@ 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, NsSerializer +from machines.serializers import InterfaceSerializer, TypeSerializer, DomainSerializer, MxSerializer, ExtensionSerializer, ServiceServersSerializer, NsSerializer from reversion import revisions as reversion from reversion.models import Version @@ -804,6 +804,23 @@ def mac_ip_dns(request): seria = mac_ip_list(request) return JSONResponse(seria) +@csrf_exempt +@login_required +@permission_required('serveur') +def service_servers(request): + service_link = Service_link.objects.all().select_related('server__domain').select_related('service') + seria = ServiceServersSerializer(service_link, many=True) + return JSONResponse(seria.data) + +@csrf_exempt +@login_required +@permission_required('serveur') +def regen_achieved(request): + obj = Service_link.objects.filter(service__in=Service.objects.filter(service_type=request.POST['service']), server__in=Interface.objects.filter(domain=Domain.objects.filter(name=request.POST['server']))) + if obj: + obj[0].done_regen() + return HttpReponse("Ok") + @csrf_exempt def login_user(request): user = authenticate(username=request.POST['username'], password=request.POST['password'])