views.py 56.6 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
2 3 4 5
# 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.
#
Gabriel Detraz's avatar
Gabriel Detraz committed
6
# Copyright © 2016-2018  Gabriel Détraz
7 8
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
Gabriel Detraz's avatar
Gabriel Detraz committed
9 10
# Copyright © 2017-2018  Maël Kervella
# Copyright © 2018  Charlie Jacomme
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#
# 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.

26
# App de gestion des machines pour re2o
Dalahro's avatar
Dalahro committed
27
# Gabriel Détraz, Augustin Lemesle
28
# Gplv2
29 30 31
"""machines.views
The views for the Machines app
"""
32 33 34

from __future__ import unicode_literals

35
from django.urls import reverse
Dalahro's avatar
Dalahro committed
36
from django.http import HttpResponse
37 38
from django.shortcuts import render, redirect
from django.contrib import messages
39
from django.contrib.auth.decorators import login_required, permission_required
40
from django.db.models import ProtectedError, F
41
from django.forms import modelformset_factory
Dalahro's avatar
Dalahro committed
42
from django.views.decorators.csrf import csrf_exempt
Dalahro's avatar
Dalahro committed
43

Dalahro's avatar
Dalahro committed
44
from rest_framework.renderers import JSONRenderer
45 46 47 48 49 50 51 52 53 54 55 56

from users.models import User
from preferences.models import GeneralOption
from re2o.utils import (
    all_active_assigned_interfaces,
    filter_active_interfaces,
    SortTable,
    re2o_paginator,
)
from re2o.acl import (
    can_create,
    can_edit,
57
    can_view,
58 59 60 61 62 63 64
    can_delete,
    can_view_all,
    can_delete_set,
)
from re2o.views import form

from .serializers import (
Maël Kervella's avatar
Maël Kervella committed
65
    FullInterfaceSerializer,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
66 67 68
    InterfaceSerializer,
    TypeSerializer,
    DomainSerializer,
Gabriel Detraz's avatar
Gabriel Detraz committed
69
    TxtSerializer,
Gabriel Detraz's avatar
Gabriel Detraz committed
70
    SrvSerializer,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
71 72 73 74 75
    MxSerializer,
    ExtensionSerializer,
    ServiceServersSerializer,
    NsSerializer,
)
Dalahro's avatar
Dalahro committed
76

LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
from .forms import (
    NewMachineForm,
    EditMachineForm,
    EditInterfaceForm,
    AddInterfaceForm,
    MachineTypeForm,
    DelMachineTypeForm,
    ExtensionForm,
    DelExtensionForm,
    EditIpTypeForm,
    IpTypeForm,
    DelIpTypeForm,
    DomainForm,
    AliasForm,
    DelAliasForm,
92 93
    SOAForm,
    DelSOAForm,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
94 95
    NsForm,
    DelNsForm,
96 97
    TxtForm,
    DelTxtForm,
Charlie Jacomme's avatar
Charlie Jacomme committed
98 99
    DNameForm,
    DelDNameForm,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
100 101 102 103 104 105
    MxForm,
    DelMxForm,
    VlanForm,
    DelVlanForm,
    ServiceForm,
    DelServiceForm,
106
    SshFpForm,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
107
    NasForm,
Gabriel Detraz's avatar
Gabriel Detraz committed
108 109 110
    DelNasForm,
    SrvForm,
    DelSrvForm,
111
    Ipv6ListForm,
112
    EditOuverturePortListForm,
113
    EditOuverturePortConfigForm,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
114 115 116 117 118 119 120
)
from .models import (
    IpType,
    Machine,
    Interface,
    MachineType,
    Extension,
121
    SOA,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
122 123 124 125 126 127 128
    Mx,
    Ns,
    Domain,
    Service,
    Service_link,
    Vlan,
    Nas,
Gabriel Detraz's avatar
Gabriel Detraz committed
129
    Txt,
Charlie Jacomme's avatar
Charlie Jacomme committed
130
    DName,
Gabriel Detraz's avatar
Gabriel Detraz committed
131
    Srv,
132
    SshFp,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
133
    OuverturePortList,
Gabriel Detraz's avatar
Gabriel Detraz committed
134
    OuverturePort,
135
    Ipv6List,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
136
)
137

Maël Kervella's avatar
Maël Kervella committed
138 139

def f_type_id(is_type_tt):
140 141 142
    """ The id that will be used in HTML to store the value of the field
    type. Depends on the fact that type is generate using typeahead or not
    """
143
    return 'id_Interface-type_hidden' if is_type_tt else 'id_Interface-type'
144

Maël Kervella's avatar
Maël Kervella committed
145

146
def generate_ipv4_choices(form_obj):
147
    """ Generate the parameter choices for the massive_bootstrap_form tag
148
    """
149
    f_ipv4 = form_obj.fields['ipv4']
150
    used_mtype_id = []
151
    choices = '{"":[{key:"",value:"Choisissez d\'abord un type de machine"},'
152 153
    mtype_id = -1

Maël Kervella's avatar
Maël Kervella committed
154 155 156 157
    for ip in (f_ipv4.queryset
               .annotate(mtype_id=F('ip_type__machinetype__id'))
               .order_by('mtype_id', 'id')):
        if mtype_id != ip.mtype_id:
158 159
            mtype_id = ip.mtype_id
            used_mtype_id.append(mtype_id)
160
            choices += '],"{t}":[{{key:"",value:"{v}"}},'.format(
Maël Kervella's avatar
Maël Kervella committed
161 162
                t=mtype_id,
                v=f_ipv4.empty_label or '""'
163 164
            )
        choices += '{{key:{k},value:"{v}"}},'.format(
Maël Kervella's avatar
Maël Kervella committed
165 166
            k=ip.id,
            v=ip.ipv4
167
        )
168

169
    for t in form_obj.fields['type'].queryset.exclude(id__in=used_mtype_id):
170 171 172 173 174
        choices += '], "'+str(t.id)+'": ['
        choices += '{key: "", value: "' + str(f_ipv4.empty_label) + '"},'
    choices += ']}'
    return choices

Maël Kervella's avatar
Maël Kervella committed
175 176

def generate_ipv4_engine(is_type_tt):
177
    """ Generate the parameter engine for the massive_bootstrap_form tag
178
    """
179 180 181 182 183 184 185 186
    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; }}'
        '}} )'
        ).format(
Maël Kervella's avatar
Maël Kervella committed
187
            type_id=f_type_id(is_type_tt)
188
        )
189

Maël Kervella's avatar
Maël Kervella committed
190 191

def generate_ipv4_match_func(is_type_tt):
192
    """ Generate the parameter match_func for the massive_bootstrap_form tag
193
    """
194 195 196 197 198 199 200 201 202 203 204
    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);'
            '}}'
        '}}'
        ).format(
Maël Kervella's avatar
Maël Kervella committed
205
            type_id=f_type_id(is_type_tt)
206
        )
207

Maël Kervella's avatar
Maël Kervella committed
208

209
def generate_ipv4_mbf_param(form_obj, is_type_tt):
210
    """ Generate all the parameters to use with the massive_bootstrap_form
211
    tag """
212
    i_choices = {'ipv4': generate_ipv4_choices(form_obj)}
Maël Kervella's avatar
Maël Kervella committed
213 214 215 216
    i_engine = {'ipv4': generate_ipv4_engine(is_type_tt)}
    i_match_func = {'ipv4': generate_ipv4_match_func(is_type_tt)}
    i_update_on = {'ipv4': [f_type_id(is_type_tt)]}
    i_gen_select = {'ipv4': False}
217
    i_mbf_param = {
218 219 220
        'choices': i_choices,
        'engine': i_engine,
        'match_func': i_match_func,
Maël Kervella's avatar
Maël Kervella committed
221 222
        'update_on': i_update_on,
        'gen_select': i_gen_select
223
    }
224
    return i_mbf_param
225

Maël Kervella's avatar
Maël Kervella committed
226

chirac's avatar
chirac committed
227
@login_required
228
@can_create(Machine)
229
@can_edit(User)
230
def new_machine(request, user, **_kwargs):
231
    """ Fonction de creation d'une machine. Cree l'objet machine,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
232
    le sous objet interface et l'objet domain à partir de model forms.
Gabriel Detraz's avatar
Gabriel Detraz committed
233
    Trop complexe, devrait être simplifié"""
Maël Kervella's avatar
Maël Kervella committed
234

235
    machine = NewMachineForm(request.POST or None, user=request.user)
Maël Kervella's avatar
Maël Kervella committed
236 237
    interface = AddInterfaceForm(
        request.POST or None,
238
        user=request.user
Maël Kervella's avatar
Maël Kervella committed
239
    )
240
    domain = DomainForm(request.POST or None, user=user)
241
    if machine.is_valid() and interface.is_valid():
242 243 244 245
        new_machine_obj = machine.save(commit=False)
        new_machine_obj.user = user
        new_interface_obj = interface.save(commit=False)
        domain.instance.interface_parent = new_interface_obj
246
        if domain.is_valid():
247
            new_domain = domain.save(commit=False)
248 249 250 251
            new_machine_obj.save()
            new_interface_obj.machine = new_machine_obj
            new_interface_obj.save()
            new_domain.interface_parent = new_interface_obj
252
            new_domain.save()
guimoz's avatar
Typo  
guimoz committed
253
            messages.success(request, "La machine a été créée")
254 255
            return redirect(reverse(
                'users:profil',
Maël Kervella's avatar
Maël Kervella committed
256
                kwargs={'userid': str(user.id)}
Maël Kervella's avatar
Maël Kervella committed
257 258 259 260 261 262 263
            ))
    i_mbf_param = generate_ipv4_mbf_param(interface, False)
    return form(
        {
            'machineform': machine,
            'interfaceform': interface,
            'domainform': domain,
264
            'i_mbf_param': i_mbf_param,
Maël Kervella's avatar
Maël Kervella committed
265
            'action_name': 'Créer une machine'
Maël Kervella's avatar
Maël Kervella committed
266 267 268 269
        },
        'machines/machine.html',
        request
    )
270

Maël Kervella's avatar
Maël Kervella committed
271

chirac's avatar
chirac committed
272
@login_required
273
@can_edit(Interface)
274
def edit_interface(request, interface_instance, **_kwargs):
Maël Kervella's avatar
Maël Kervella committed
275 276 277
    """ Edition d'une interface. Distingue suivant les droits les valeurs
    de interfaces et machines que l'user peut modifier infra permet de
    modifier le propriétaire"""
278

279 280 281 282 283
    machine_form = EditMachineForm(
        request.POST or None,
        instance=interface_instance.machine,
        user=request.user
    )
Maël Kervella's avatar
Maël Kervella committed
284 285 286 287 288 289 290 291 292 293 294 295
    interface_form = EditInterfaceForm(
        request.POST or None,
        instance=interface_instance,
        user=request.user
    )
    domain_form = DomainForm(
        request.POST or None,
        instance=interface_instance.domain
    )
    if (machine_form.is_valid() and
            interface_form.is_valid() and
            domain_form.is_valid()):
296 297 298
        new_machine_obj = machine_form.save(commit=False)
        new_interface_obj = interface_form.save(commit=False)
        new_domain_obj = domain_form.save(commit=False)
299
        if machine_form.changed_data:
300
            new_machine_obj.save()
301
        if interface_form.changed_data:
302
            new_interface_obj.save()
303
        if domain_form.changed_data:
304
            new_domain_obj.save()
305
        messages.success(request, "La machine a été modifiée")
306 307
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
            kwargs={'userid': str(interface_instance.machine.user.id)}
        ))
    i_mbf_param = generate_ipv4_mbf_param(interface_form, False)
    return form(
        {
            'machineform': machine_form,
            'interfaceform': interface_form,
            'domainform': domain_form,
            'i_mbf_param': i_mbf_param,
            'action_name': 'Editer une interface'
        },
        'machines/machine.html',
        request
    )

323

324
@login_required
325
@can_delete(Machine)
326
def del_machine(request, machine, **_kwargs):
Gabriel Detraz's avatar
Gabriel Detraz committed
327
    """ Supprime une machine, interfaces en mode cascade"""
328
    if request.method == "POST":
329
        machine.delete()
330
        messages.success(request, "La machine a été détruite")
331 332
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
333 334 335 336 337 338 339 340
            kwargs={'userid': str(machine.user.id)}
        ))
    return form(
        {'objet': machine, 'objet_name': 'machine'},
        'machines/delete.html',
        request
    )

341

chirac's avatar
chirac committed
342
@login_required
343
@can_create(Interface)
344
@can_edit(Machine)
345
def new_interface(request, machine, **_kwargs):
Gabriel Detraz's avatar
Gabriel Detraz committed
346
    """ Ajoute une interface et son domain associé à une machine existante"""
347

348
    interface_form = AddInterfaceForm(request.POST or None, user=request.user)
349
    domain_form = DomainForm(request.POST or None)
350
    if interface_form.is_valid():
351 352 353
        new_interface_obj = interface_form.save(commit=False)
        domain_form.instance.interface_parent = new_interface_obj
        new_interface_obj.machine = machine
354
        if domain_form.is_valid():
355 356 357 358
            new_domain_obj = domain_form.save(commit=False)
            new_interface_obj.save()
            new_domain_obj.interface_parent = new_interface_obj
            new_domain_obj.save()
359
            messages.success(request, "L'interface a été ajoutée")
360 361
            return redirect(reverse(
                'users:profil',
Maël Kervella's avatar
Maël Kervella committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375
                kwargs={'userid': str(machine.user.id)}
            ))
    i_mbf_param = generate_ipv4_mbf_param(interface_form, False)
    return form(
        {
            'interfaceform': interface_form,
            'domainform': domain_form,
            'i_mbf_param': i_mbf_param,
            'action_name': 'Créer une interface'
        },
        'machines/machine.html',
        request
    )

376

377
@login_required
378
@can_delete(Interface)
379
def del_interface(request, interface, **_kwargs):
Gabriel Detraz's avatar
Gabriel Detraz committed
380
    """ Supprime une interface. Domain objet en mode cascade"""
381
    if request.method == "POST":
382
        machine = interface.machine
383 384 385
        interface.delete()
        if not machine.interface_set.all():
            machine.delete()
386
        messages.success(request, "L'interface a été détruite")
387 388
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
389 390 391 392 393 394 395 396
            kwargs={'userid': str(request.user.id)}
        ))
    return form(
        {'objet': interface, 'objet_name': 'interface'},
        'machines/delete.html',
        request
    )

397

398 399 400
@login_required
@can_create(Ipv6List)
@can_edit(Interface)
401
def new_ipv6list(request, interface, **_kwargs):
402
    """Nouvelle ipv6"""
403
    ipv6list_instance = Ipv6List(interface=interface)
Maël Kervella's avatar
Maël Kervella committed
404 405 406 407 408
    ipv6 = Ipv6ListForm(
        request.POST or None,
        instance=ipv6list_instance,
        user=request.user
    )
409
    if ipv6.is_valid():
410
        ipv6.save()
411 412 413
        messages.success(request, "Ipv6 ajoutée")
        return redirect(reverse(
            'machines:index-ipv6',
Maël Kervella's avatar
Maël Kervella committed
414 415 416 417 418 419 420 421
            kwargs={'interfaceid': str(interface.id)}
        ))
    return form(
        {'ipv6form': ipv6, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

422 423 424

@login_required
@can_edit(Ipv6List)
425
def edit_ipv6list(request, ipv6list_instance, **_kwargs):
426
    """Edition d'une ipv6"""
Maël Kervella's avatar
Maël Kervella committed
427 428 429 430 431
    ipv6 = Ipv6ListForm(
        request.POST or None,
        instance=ipv6list_instance,
        user=request.user
    )
432
    if ipv6.is_valid():
433 434 435
        if ipv6.changed_data:
            ipv6.save()
            messages.success(request, "Ipv6 modifiée")
436 437
        return redirect(reverse(
            'machines:index-ipv6',
Maël Kervella's avatar
Maël Kervella committed
438 439 440 441 442 443 444 445
            kwargs={'interfaceid': str(ipv6list_instance.interface.id)}
        ))
    return form(
        {'ipv6form': ipv6, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

446 447 448

@login_required
@can_delete(Ipv6List)
449
def del_ipv6list(request, ipv6list, **_kwargs):
450 451 452
    """ Supprime une ipv6"""
    if request.method == "POST":
        interfaceid = ipv6list.interface.id
453
        ipv6list.delete()
454 455 456
        messages.success(request, "L'ipv6 a été détruite")
        return redirect(reverse(
            'machines:index-ipv6',
Maël Kervella's avatar
Maël Kervella committed
457 458 459 460 461 462 463 464
            kwargs={'interfaceid': str(interfaceid)}
        ))
    return form(
        {'objet': ipv6list, 'objet_name': 'ipv6'},
        'machines/delete.html',
        request
    )

465

466
@login_required
467
@can_create(SshFp)
468
@can_edit(Machine)
469 470 471 472
def new_sshfp(request, machine, **_kwargs):
    """Creates an SSHFP record associated with a machine"""
    sshfp_instance = SshFp(machine=machine)
    sshfp = SshFpForm(
473
        request.POST or None,
474
        instance=sshfp_instance
475
    )
476 477 478
    if sshfp.is_valid():
        sshfp.save()
        messages.success(request, "The SSHFP record was added")
479
        return redirect(reverse(
480
            'machines:index-sshfp',
481
            kwargs={'machineid': str(machine.id)}
482 483
        ))
    return form(
484
        {'sshfpform': sshfp, 'action_name': 'Create'},
485 486 487 488 489 490
        'machines/machine.html',
        request
    )


@login_required
491 492 493 494
@can_edit(SshFp)
def edit_sshfp(request, sshfp_instance, **_kwargs):
    """Edits an SSHFP record"""
    sshfp = SshFpForm(
495
        request.POST or None,
496
        instance=sshfp_instance
497
    )
498 499 500 501
    if sshfp.is_valid():
        if sshfp.changed_data:
            sshfp.save()
            messages.success(request, "The SSHFP record was edited")
502
        return redirect(reverse(
503 504
            'machines:index-sshfp',
            kwargs={'machineid': str(sshfp_instance.machine.id)}
505 506
        ))
    return form(
507
        {'sshfpform': sshfp, 'action_name': 'Edit'},
508 509 510 511 512 513
        'machines/machine.html',
        request
    )


@login_required
514 515 516
@can_delete(SshFp)
def del_sshfp(request, sshfp, **_kwargs):
    """Deletes an SSHFP record"""
517
    if request.method == "POST":
518 519 520
        machineid = sshfp.machine.id
        sshfp.delete()
        messages.success(request, "The SSHFP record was deleted")
521
        return redirect(reverse(
522
            'machines:index-sshfp',
523 524 525
            kwargs={'machineid': str(machineid)}
        ))
    return form(
526
        {'objet': sshfp, 'objet_name': 'sshfp'},
527 528 529 530 531
        'machines/delete.html',
        request
    )


chirac's avatar
chirac committed
532
@login_required
533
@can_create(IpType)
chirac's avatar
chirac committed
534
def add_iptype(request):
Maël Kervella's avatar
Maël Kervella committed
535 536
    """ Ajoute un range d'ip. Intelligence dans le models, fonction views
    minimaliste"""
537

chirac's avatar
chirac committed
538 539
    iptype = IpTypeForm(request.POST or None)
    if iptype.is_valid():
540
        iptype.save()
chirac's avatar
chirac committed
541
        messages.success(request, "Ce type d'ip a été ajouté")
542
        return redirect(reverse('machines:index-iptype'))
Maël Kervella's avatar
Maël Kervella committed
543 544 545 546 547 548
    return form(
        {'iptypeform': iptype, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

chirac's avatar
chirac committed
549 550

@login_required
551
@can_edit(IpType)
552
def edit_iptype(request, iptype_instance, **_kwargs):
Maël Kervella's avatar
Maël Kervella committed
553 554
    """ Edition d'un range. Ne permet pas de le redimensionner pour éviter
    l'incohérence"""
555

556
    iptype = EditIpTypeForm(request.POST or None, instance=iptype_instance)
chirac's avatar
chirac committed
557
    if iptype.is_valid():
558 559 560
        if iptype.changed_data:
            iptype.save()
            messages.success(request, "Type d'ip modifié")
561
        return redirect(reverse('machines:index-iptype'))
Maël Kervella's avatar
Maël Kervella committed
562 563 564 565 566 567
    return form(
        {'iptypeform': iptype, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

chirac's avatar
chirac committed
568 569

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
570 571
@can_delete_set(IpType)
def del_iptype(request, instances):
Gabriel Detraz's avatar
Gabriel Detraz committed
572
    """ Suppression d'un range ip. Supprime les objets ip associés"""
Gabriel Detraz's avatar
Gabriel Detraz committed
573
    iptype = DelIpTypeForm(request.POST or None, instances=instances)
chirac's avatar
chirac committed
574 575 576 577
    if iptype.is_valid():
        iptype_dels = iptype.cleaned_data['iptypes']
        for iptype_del in iptype_dels:
            try:
578
                iptype_del.delete()
chirac's avatar
chirac committed
579 580
                messages.success(request, "Le type d'ip a été supprimé")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
581 582 583 584 585
                messages.error(
                    request,
                    ("Le type d'ip %s est affectée à au moins une machine, "
                     "vous ne pouvez pas le supprimer" % iptype_del)
                )
586
        return redirect(reverse('machines:index-iptype'))
Maël Kervella's avatar
Maël Kervella committed
587 588 589 590 591 592
    return form(
        {'iptypeform': iptype, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

chirac's avatar
chirac committed
593

chirac's avatar
chirac committed
594
@login_required
595
@can_create(MachineType)
chirac's avatar
chirac committed
596
def add_machinetype(request):
597
    """ View used to add a Machinetype object """
chirac's avatar
chirac committed
598 599
    machinetype = MachineTypeForm(request.POST or None)
    if machinetype.is_valid():
600
        machinetype.save()
chirac's avatar
chirac committed
601
        messages.success(request, "Ce type de machine a été ajouté")
602
        return redirect(reverse('machines:index-machinetype'))
Maël Kervella's avatar
Maël Kervella committed
603 604 605 606 607 608
    return form(
        {'machinetypeform': machinetype, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

chirac's avatar
chirac committed
609

chirac's avatar
chirac committed
610
@login_required
611
@can_edit(MachineType)
612
def edit_machinetype(request, machinetype_instance, **_kwargs):
613
    """ View used to edit a MachineType object """
Maël Kervella's avatar
Maël Kervella committed
614 615 616 617
    machinetype = MachineTypeForm(
        request.POST or None,
        instance=machinetype_instance
    )
618
    if machinetype.is_valid():
619 620 621
        if machinetype.changed_data:
            machinetype.save()
            messages.success(request, "Type de machine modifié")
622
        return redirect(reverse('machines:index-machinetype'))
Maël Kervella's avatar
Maël Kervella committed
623 624 625 626 627 628
    return form(
        {'machinetypeform': machinetype, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

629

chirac's avatar
chirac committed
630
@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
631 632
@can_delete_set(MachineType)
def del_machinetype(request, instances):
633
    """ View used to delete a MachineType object """
Gabriel Detraz's avatar
Gabriel Detraz committed
634
    machinetype = DelMachineTypeForm(request.POST or None, instances=instances)
chirac's avatar
chirac committed
635 636 637 638
    if machinetype.is_valid():
        machinetype_dels = machinetype.cleaned_data['machinetypes']
        for machinetype_del in machinetype_dels:
            try:
639
                machinetype_del.delete()
chirac's avatar
chirac committed
640 641
                messages.success(request, "Le type de machine a été supprimé")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
642 643 644 645 646 647
                messages.error(
                    request,
                    ("Le type de machine %s est affectée à au moins une "
                     "machine, vous ne pouvez pas le supprimer"
                     % machinetype_del)
                )
648
        return redirect(reverse('machines:index-machinetype'))
Maël Kervella's avatar
Maël Kervella committed
649 650 651 652 653 654
    return form(
        {'machinetypeform': machinetype, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

chirac's avatar
chirac committed
655

656
@login_required
657
@can_create(Extension)
658
def add_extension(request):
659
    """ View used to add an Extension object """
660 661
    extension = ExtensionForm(request.POST or None)
    if extension.is_valid():
662
        extension.save()
663
        messages.success(request, "Cette extension a été ajoutée")
664
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
665 666 667 668 669 670
    return form(
        {'extensionform': extension, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

671 672

@login_required
673
@can_edit(Extension)
674
def edit_extension(request, extension_instance, **_kwargs):
675
    """ View used to edit an Extension object """
Maël Kervella's avatar
Maël Kervella committed
676 677 678 679
    extension = ExtensionForm(
        request.POST or None,
        instance=extension_instance
    )
680
    if extension.is_valid():
681 682 683
        if extension.changed_data:
            extension.save()
            messages.success(request, "Extension modifiée")
684
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
685 686 687 688 689 690
    return form(
        {'extensionform': extension, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

691 692

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
693 694
@can_delete_set(Extension)
def del_extension(request, instances):
695
    """ View used to delete an Extension object """
Gabriel Detraz's avatar
Gabriel Detraz committed
696
    extension = DelExtensionForm(request.POST or None, instances=instances)
697 698 699 700
    if extension.is_valid():
        extension_dels = extension.cleaned_data['extensions']
        for extension_del in extension_dels:
            try:
701
                extension_del.delete()
702 703
                messages.success(request, "L'extension a été supprimée")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
704 705 706 707 708 709
                messages.error(
                    request,
                    ("L'extension %s est affectée à au moins un type de "
                     "machine, vous ne pouvez pas la supprimer"
                     % extension_del)
                )
710
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
711 712 713 714 715 716
    return form(
        {'extensionform': extension, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

717

718
@login_required
719
@can_create(SOA)
720
def add_soa(request):
721
    """ View used to add a SOA object """
722 723
    soa = SOAForm(request.POST or None)
    if soa.is_valid():
724
        soa.save()
725
        messages.success(request, "Cet enregistrement SOA a été ajouté")
726
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
727 728 729 730 731 732
    return form(
        {'soaform': soa, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

733 734

@login_required
735
@can_edit(SOA)
736
def edit_soa(request, soa_instance, **_kwargs):
737
    """ View used to edit a SOA object """
738 739
    soa = SOAForm(request.POST or None, instance=soa_instance)
    if soa.is_valid():
740 741 742
        if soa.changed_data:
            soa.save()
            messages.success(request, "SOA modifié")
743
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
744 745 746 747 748 749
    return form(
        {'soaform': soa, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

750 751

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
752 753
@can_delete_set(SOA)
def del_soa(request, instances):
754
    """ View used to delete a SOA object """
Gabriel Detraz's avatar
Gabriel Detraz committed
755
    soa = DelSOAForm(request.POST or None, instances=instances)
756 757 758 759
    if soa.is_valid():
        soa_dels = soa.cleaned_data['soa']
        for soa_del in soa_dels:
            try:
760
                soa_del.delete()
761 762
                messages.success(request, "Le SOA a été supprimée")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
763 764 765 766 767
                messages.error(
                    request,
                    ("Erreur le SOA suivant %s ne peut être supprimé"
                     % soa_del)
                )
768
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
769 770 771 772 773 774
    return form(
        {'soaform': soa, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

775

776
@login_required
777
@can_create(Mx)
778
def add_mx(request):
779
    """ View used to add a MX object """
780 781
    mx = MxForm(request.POST or None)
    if mx.is_valid():
782
        mx.save()
783
        messages.success(request, "Cet enregistrement mx a été ajouté")
784
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
785 786 787 788 789 790
    return form(
        {'mxform': mx, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

791 792

@login_required
793
@can_edit(Mx)
794
def edit_mx(request, mx_instance, **_kwargs):
795
    """ View used to edit a MX object """
796 797
    mx = MxForm(request.POST or None, instance=mx_instance)
    if mx.is_valid():
798 799 800
        if mx.changed_data:
            mx.save()
            messages.success(request, "Mx modifié")
801
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
802 803 804 805 806 807
    return form(
        {'mxform': mx, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

808 809

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
810 811
@can_delete_set(Mx)
def del_mx(request, instances):
812
    """ View used to delete a MX object """
Gabriel Detraz's avatar
Gabriel Detraz committed
813
    mx = DelMxForm(request.POST or None, instances=instances)
814 815 816 817
    if mx.is_valid():
        mx_dels = mx.cleaned_data['mx']
        for mx_del in mx_dels:
            try:
818
                mx_del.delete()
819 820
                messages.success(request, "L'mx a été supprimée")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
821 822 823 824 825
                messages.error(
                    request,
                    ("Erreur le Mx suivant %s ne peut être supprimé"
                     % mx_del)
                )
826
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
827 828 829 830 831 832
    return form(
        {'mxform': mx, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

833

834
@login_required
835
@can_create(Ns)
836
def add_ns(request):
837
    """ View used to add a NS object """
838 839
    ns = NsForm(request.POST or None)
    if ns.is_valid():
840
        ns.save()
841
        messages.success(request, "Cet enregistrement ns a été ajouté")
842
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
843 844 845 846 847 848
    return form(
        {'nsform': ns, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

849 850

@login_required
851
@can_edit(Ns)
852
def edit_ns(request, ns_instance, **_kwargs):
853
    """ View used to edit a NS object """
854 855
    ns = NsForm(request.POST or None, instance=ns_instance)
    if ns.is_valid():
856 857 858
        if ns.changed_data:
            ns.save()
            messages.success(request, "Ns modifié")
859
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
860 861 862 863 864 865
    return form(
        {'nsform': ns, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

866 867

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
868 869
@can_delete_set(Ns)
def del_ns(request, instances):
870
    """ View used to delete a NS object """
Gabriel Detraz's avatar
Gabriel Detraz committed
871
    ns = DelNsForm(request.POST or None, instances=instances)
872 873 874 875
    if ns.is_valid():
        ns_dels = ns.cleaned_data['ns']
        for ns_del in ns_dels:
            try:
876
                ns_del.delete()
877 878
                messages.success(request, "Le ns a été supprimée")
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
879 880 881 882 883
                messages.error(
                    request,
                    ("Erreur le Ns suivant %s ne peut être supprimé"
                     % ns_del)
                )
884
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
885 886 887 888 889 890
    return form(
        {'nsform': ns, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

Charlie Jacomme's avatar
Charlie Jacomme committed
891 892 893 894 895 896 897
@login_required
@can_create(DName)
def add_dname(request):
    """ View used to add a DName object """
    dname = DNameForm(request.POST or None)
    if dname.is_valid():
        dname.save()
Maël Kervella's avatar
Maël Kervella committed
898
        messages.success(request, "This DNAME record has been added")
Charlie Jacomme's avatar
Charlie Jacomme committed
899 900
        return redirect(reverse('machines:index-extension'))
    return form(
Maël Kervella's avatar
Maël Kervella committed
901
        {'dnameform': dname, 'action_name': "Create"},
Charlie Jacomme's avatar
Charlie Jacomme committed
902 903 904 905 906 907 908 909 910 911 912 913 914
        'machines/machine.html',
        request
    )


@login_required
@can_edit(DName)
def edit_dname(request, dname_instance, **_kwargs):
    """ View used to edit a DName object """
    dname = DNameForm(request.POST or None, instance=dname_instance)
    if dname.is_valid():
        if dname.changed_data:
            dname.save()
Maël Kervella's avatar
Maël Kervella committed
915
            messages.success(request, "DName successfully edited")
Charlie Jacomme's avatar
Charlie Jacomme committed
916 917
        return redirect(reverse('machines:index-extension'))
    return form(
Maël Kervella's avatar
Maël Kervella committed
918
        {'dnameform': dname, 'action_name': "Edit"},
Charlie Jacomme's avatar
Charlie Jacomme committed
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
        'machines/machine.html',
        request
    )


@login_required
@can_delete_set(DName)
def del_dname(request, instances):
    """ View used to delete a DName object """
    dname = DelDNameForm(request.POST or None, instances=instances)
    if dname.is_valid():
        dname_dels = dname.cleaned_data['dname']
        for dname_del in dname_dels:
            try:
                dname_del.delete()
Maël Kervella's avatar
Maël Kervella committed
934 935
                messages.success(request,
                                 "The DNAME %s has been deleted" % dname_del)
Charlie Jacomme's avatar
Charlie Jacomme committed
936 937 938
            except ProtectedError:
                messages.error(
                    request,
Maël Kervella's avatar
Maël Kervella committed
939
                    "The DNAME %s can not be deleted" % dname_del
Charlie Jacomme's avatar
Charlie Jacomme committed
940 941 942
                )
        return redirect(reverse('machines:index-extension'))
    return form(
Maël Kervella's avatar
Maël Kervella committed
943
        {'dnameform': dname, 'action_name': 'Delete'},
Charlie Jacomme's avatar
Charlie Jacomme committed
944 945 946 947
        'machines/machine.html',
        request
    )

948

Gabriel Detraz's avatar
Gabriel Detraz committed
949
@login_required
950
@can_create(Txt)
951
def add_txt(request):
952
    """ View used to add a TXT object """
953 954
    txt = TxtForm(request.POST or None)
    if txt.is_valid():
955
        txt.save()
Gabriel Detraz's avatar
Gabriel Detraz committed
956
        messages.success(request, "Cet enregistrement text a été ajouté")
957
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
958 959 960 961 962 963
    return form(
        {'txtform': txt, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

Gabriel Detraz's avatar
Gabriel Detraz committed
964 965

@login_required
966
@can_edit(Txt)
967
def edit_txt(request, txt_instance, **_kwargs):
968
    """ View used to edit a TXT object """
969 970
    txt = TxtForm(request.POST or None, instance=txt_instance)
    if txt.is_valid():
971 972 973
        if txt.changed_data:
            txt.save()
            messages.success(request, "Txt modifié")
974
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
975 976 977 978 979 980
    return form(
        {'txtform': txt, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

Gabriel Detraz's avatar
Gabriel Detraz committed
981 982

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
983 984
@can_delete_set(Txt)
def del_txt(request, instances):
985
    """ View used to delete a TXT object """
Gabriel Detraz's avatar
Gabriel Detraz committed
986
    txt = DelTxtForm(request.POST or None, instances=instances)
987 988 989
    if txt.is_valid():
        txt_dels = txt.cleaned_data['txt']
        for txt_del in txt_dels:
Gabriel Detraz's avatar
Gabriel Detraz committed
990
            try:
991
                txt_del.delete()
992
                messages.success(request, "Le txt a été supprimé")
Gabriel Detraz's avatar
Gabriel Detraz committed
993
            except ProtectedError:
Maël Kervella's avatar
Maël Kervella committed
994 995 996 997 998
                messages.error(
                    request,
                    ("Erreur le Txt suivant %s ne peut être supprimé"
                     % txt_del)
                )
999
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
1000 1001 1002 1003 1004 1005
    return form(
        {'txtform': txt, 'action_name': 'Supprimer'},
        'machines/machine.html',
        request
    )

Gabriel Detraz's avatar
Gabriel Detraz committed
1006

Gabriel Detraz's avatar
Gabriel Detraz committed
1007
@login_required
1008
@can_create(Srv)
Gabriel Detraz's avatar
Gabriel Detraz committed
1009
def add_srv(request):
1010
    """ View used to add a SRV object """
Gabriel Detraz's avatar
Gabriel Detraz committed
1011 1012
    srv = SrvForm(request.POST or None)
    if srv.is_valid():
1013
        srv.save()
Gabriel Detraz's avatar
Gabriel Detraz committed
1014 1015
        messages.success(request, "Cet enregistrement srv a été ajouté")
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
1016 1017 1018 1019 1020 1021
    return form(
        {'srvform': srv, 'action_name': 'Créer'},
        'machines/machine.html',
        request
    )

Gabriel Detraz's avatar
Gabriel Detraz committed
1022 1023

@login_required
1024
@can_edit(Srv)
1025
def edit_srv(request, srv_instance, **_kwargs):
1026
    """ View used to edit a SRV object """
Gabriel Detraz's avatar
Gabriel Detraz committed
1027 1028
    srv = SrvForm(request.POST or None, instance=srv_instance)
    if srv.is_valid():
1029 1030 1031
        if srv.changed_data:
            srv.save()
            messages.success(request, "Srv modifié")
Gabriel Detraz's avatar
Gabriel Detraz committed
1032
        return redirect(reverse('machines:index-extension'))
Maël Kervella's avatar
Maël Kervella committed
1033 1034 1035 1036 1037 1038
    return form(
        {'srvform': srv, 'action_name': 'Editer'},
        'machines/machine.html',
        request
    )

Gabriel Detraz's avatar
Gabriel Detraz committed
1039 1040

@login_required
Gabriel Detraz's avatar
Gabriel Detraz committed
1041 1042
@can_delete_set(Srv)
def del_srv(request, instances):
1043
    """ View used to delete a SRV object """
Gabriel Detraz's avatar
Gabriel Detraz committed
1044
    srv = DelSrvForm(request.POST or None, instances=instances)
Gabriel Detraz's avatar
Gabriel Detraz committed