8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-27 15:12:25 +00:00
re2o/machines/views.py

1500 lines
49 KiB
Python

# -*- mode: python; coding: utf-8 -*-
# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2016-2018 Gabriel Détraz
# Copyright © 2017 Lara Kermarec
# Copyright © 2017 Augustin Lemesle
# Copyright © 2017-2018 Maël Kervella
# Copyright © 2018 Charlie Jacomme
#
# 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.
# App de gestion des machines pour re2o
# Gabriel Détraz, Augustin Lemesle
# Gplv2
"""machines.views
The views for the Machines app
"""
from __future__ import unicode_literals
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.db import IntegrityError
from django.db.models import F, ProtectedError
from django.forms import modelformset_factory
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from preferences.models import GeneralOption
from re2o.acl import (can_create, can_delete, can_delete_set, can_edit,
can_view, can_view_all)
from re2o.base import SortTable, re2o_paginator
from re2o.utils import all_active_assigned_interfaces, filter_active_interfaces
from re2o.views import form
from users.models import User
from .forms import (AddInterfaceForm, AliasForm, DelAliasForm, DelDNameForm,
DelExtensionForm, DelIpTypeForm, DelMachineTypeForm,
DelMxForm, DelNasForm, DelNsForm, DelRoleForm,
DelServiceForm, DelSOAForm, DelSrvForm, DelTxtForm,
DelVlanForm, DNameForm, DomainForm, EditInterfaceForm,
EditIpTypeForm, EditMachineForm,
EditOuverturePortConfigForm, EditOuverturePortListForm,
ExtensionForm, IpTypeForm, Ipv6ListForm, MachineTypeForm,
MxForm, NasForm, NewMachineForm, NsForm, RoleForm,
ServiceForm, SOAForm, SrvForm, SshFpForm, TxtForm,
VlanForm)
from .models import (SOA, DName, Domain, Extension, Interface, IpType,
Ipv6List, Machine, MachineType, Mx, Nas, Ns,
OuverturePort, OuverturePortList, Role, Service,
Service_link, Srv, SshFp, Txt, Vlan, regen)
@login_required
@can_create(Machine)
@can_edit(User)
def new_machine(request, user, **_kwargs):
"""View used to create machines.
Creates the object, the underlying interface and domain objects from model
forms. Too complex, should be simplified.
"""
machine = NewMachineForm(request.POST or None, user=request.user)
interface = AddInterfaceForm(request.POST or None, user=request.user)
domain = DomainForm(
request.POST or None, user=user, initial={"name": user.get_next_domain_name()}
)
if machine.is_valid() and interface.is_valid():
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
if domain.is_valid():
new_domain = domain.save(commit=False)
new_machine_obj.save()
new_interface_obj.machine = new_machine_obj
new_interface_obj.save()
new_domain.interface_parent = new_interface_obj
new_domain.save()
messages.success(request, _("The machine was created."))
return redirect(reverse("users:profil", kwargs={"userid": str(user.id)}))
return form(
{
"machineform": machine,
"interfaceform": interface,
"domainform": domain,
"action_name": _("Add"),
},
"machines/machine.html",
request,
)
@login_required
@can_edit(Interface)
def edit_interface(request, interface_instance, **_kwargs):
"""View used to edit interfaces.
The values a user can change depends on their rights.
"""
machine_form = EditMachineForm(
request.POST or None, instance=interface_instance.machine, user=request.user
)
interface_form = EditInterfaceForm(
request.POST or None, instance=interface_instance, user=request.user
)
domain_form = DomainForm(
request.POST or None, instance=interface_instance.domain, user=request.user
)
if machine_form.is_valid() and interface_form.is_valid() and domain_form.is_valid():
new_machine_obj = machine_form.save(commit=False)
new_interface_obj = interface_form.save(commit=False)
new_domain_obj = domain_form.save(commit=False)
if machine_form.changed_data:
new_machine_obj.save()
if interface_form.changed_data:
new_interface_obj.save()
new_domain_obj.save()
messages.success(request, _("The machine was edited."))
return redirect(
reverse(
"users:profil",
kwargs={"userid": str(interface_instance.machine.user.id)},
)
)
return form(
{
"machineform": machine_form,
"interfaceform": interface_form,
"domainform": domain_form,
"action_name": _("Edit"),
},
"machines/machine.html",
request,
)
@login_required
@can_delete(Machine)
def del_machine(request, machine, **_kwargs):
"""View used to delete machines, and the interfaces in cascade."""
if request.method == "POST":
machine.delete()
messages.success(request, _("The machine was deleted."))
return redirect(
reverse("users:profil", kwargs={"userid": str(machine.user.id)})
)
return form(
{"objet": machine, "objet_name": _("machine")}, "machines/delete.html", request
)
@login_required
@can_create(Interface)
@can_edit(Machine)
def new_interface(request, machine, **_kwargs):
"""View used to create interfaces and the associated domains related to a
machine.
"""
interface_form = AddInterfaceForm(request.POST or None, user=request.user)
domain_form = DomainForm(
request.POST or None,
user=request.user,
initial={"name": machine.user.get_next_domain_name()},
)
if interface_form.is_valid():
new_interface_obj = interface_form.save(commit=False)
domain_form.instance.interface_parent = new_interface_obj
new_interface_obj.machine = machine
if domain_form.is_valid():
new_domain_obj = domain_form.save(commit=False)
new_interface_obj.save()
new_domain_obj.interface_parent = new_interface_obj
new_domain_obj.save()
messages.success(request, _("The interface was created."))
return redirect(
reverse("users:profil", kwargs={"userid": str(machine.user.id)})
)
return form(
{
"interfaceform": interface_form,
"domainform": domain_form,
"action_name": _("Add"),
},
"machines/machine.html",
request,
)
@login_required
@can_delete(Interface)
def del_interface(request, interface, **_kwargs):
"""View used to delete interfaces, and the domains in cascade."""
if request.method == "POST":
machine = interface.machine
interface.delete()
if not machine.interface_set.all():
machine.delete()
messages.success(request, _("The interface was deleted."))
return redirect(
reverse("users:profil", kwargs={"userid": str(request.user.id)})
)
return form(
{"objet": interface, "objet_name": _("interface")},
"machines/delete.html",
request,
)
@login_required
@can_create(Ipv6List)
@can_edit(Interface)
def new_ipv6list(request, interface, **_kwargs):
"""View used to create IPv6 addresses lists."""
ipv6list_instance = Ipv6List(interface=interface)
ipv6 = Ipv6ListForm(
request.POST or None, instance=ipv6list_instance, user=request.user
)
if ipv6.is_valid():
ipv6.save()
messages.success(request, _("The IPv6 addresses list was created."))
return redirect(
reverse("machines:index-ipv6", kwargs={"interfaceid": str(interface.id)})
)
return form(
{"ipv6form": ipv6, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Ipv6List)
def edit_ipv6list(request, ipv6list_instance, **_kwargs):
"""View used to edit IPv6 addresses lists."""
ipv6 = Ipv6ListForm(
request.POST or None, instance=ipv6list_instance, user=request.user
)
if ipv6.is_valid():
if ipv6.changed_data:
ipv6.save()
messages.success(request, _("The IPv6 addresses list was edited."))
return redirect(
reverse(
"machines:index-ipv6",
kwargs={"interfaceid": str(ipv6list_instance.interface.id)},
)
)
return form(
{"ipv6form": ipv6, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete(Ipv6List)
def del_ipv6list(request, ipv6list, **_kwargs):
"""View used to delete IPv6 addresses lists."""
if request.method == "POST":
interfaceid = ipv6list.interface.id
ipv6list.delete()
messages.success(request, _("The IPv6 addresses list was deleted."))
return redirect(
reverse("machines:index-ipv6", kwargs={"interfaceid": str(interfaceid)})
)
return form(
{"objet": ipv6list, "objet_name": _("IPv6 addresses list")},
"machines/delete.html",
request,
)
@login_required
@can_create(SshFp)
@can_edit(Machine)
def new_sshfp(request, machine, **_kwargs):
"""View used to create SSHFP records associated with machines."""
sshfp_instance = SshFp(machine=machine)
sshfp = SshFpForm(request.POST or None, instance=sshfp_instance)
if sshfp.is_valid():
sshfp.save()
messages.success(request, _("The SSHFP record was created."))
return redirect(
reverse("machines:index-sshfp", kwargs={"machineid": str(machine.id)})
)
return form(
{"sshfpform": sshfp, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(SshFp)
def edit_sshfp(request, sshfp_instance, **_kwargs):
"""View used to edit SSHFP records."""
sshfp = SshFpForm(request.POST or None, instance=sshfp_instance)
if sshfp.is_valid():
if sshfp.changed_data:
sshfp.save()
messages.success(request, _("The SSHFP record was edited."))
return redirect(
reverse(
"machines:index-sshfp",
kwargs={"machineid": str(sshfp_instance.machine.id)},
)
)
return form(
{"sshfpform": sshfp, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete(SshFp)
def del_sshfp(request, sshfp, **_kwargs):
"""View used to delete SSHFP records."""
if request.method == "POST":
machineid = sshfp.machine.id
sshfp.delete()
messages.success(request, _("The SSHFP record was deleted."))
return redirect(
reverse("machines:index-sshfp", kwargs={"machineid": str(machineid)})
)
return form(
{"objet": sshfp, "objet_name": _("SSHFP record")},
"machines/delete.html",
request,
)
@login_required
@can_create(IpType)
def add_iptype(request):
"""View used to create IP ranges.
The view function is simple, the intelligence is in the model.
"""
iptype = IpTypeForm(request.POST or None)
if iptype.is_valid():
iptype.save()
messages.success(request, _("The IP type was created."))
return redirect(reverse("machines:index-iptype"))
return form(
{"iptypeform": iptype, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(IpType)
def edit_iptype(request, iptype_instance, **_kwargs):
"""View used to edit IP ranges.
Changing the size of the range is not possible to prevent inconsistency.
"""
iptype = EditIpTypeForm(request.POST or None, instance=iptype_instance)
if iptype.is_valid():
if iptype.changed_data:
try:
iptype.save()
messages.success(request, _("The IP type was edited."))
except IntegrityError as e:
messages.success(
request, _("This IP type change would create duplicated domains")
)
return redirect(reverse("machines:index-iptype"))
return form(
{"iptypeform": iptype, "action_name": _("Edit")},
"machines/machine.html",
request,
)
@login_required
@can_delete_set(IpType)
def del_iptype(request, instances):
"""View used to delete IP ranges.
Deletes the related IP objects.
"""
iptype = DelIpTypeForm(request.POST or None, instances=instances)
if iptype.is_valid():
iptype_dels = iptype.cleaned_data["iptypes"]
for iptype_del in iptype_dels:
try:
iptype_del.delete()
messages.success(request, _("The IP type was deleted."))
except ProtectedError:
messages.error(
request,
(
_(
"The IP type %s is assigned to at least one machine,"
" you can't delete it."
)
% iptype_del
),
)
return redirect(reverse("machines:index-iptype"))
return form(
{"iptypeform": iptype, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_create(MachineType)
def add_machinetype(request):
"""View used to create machine types."""
machinetype = MachineTypeForm(request.POST or None)
if machinetype.is_valid():
machinetype.save()
messages.success(request, _("The machine type was created."))
return redirect(reverse("machines:index-machinetype"))
return form(
{"machinetypeform": machinetype, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(MachineType)
def edit_machinetype(request, machinetype_instance, **_kwargs):
"""View used to edit machine types."""
machinetype = MachineTypeForm(request.POST or None, instance=machinetype_instance)
if machinetype.is_valid():
if machinetype.changed_data:
try:
machinetype.save()
messages.success(request, _("The machine type was edited."))
except IntegrityError as e:
messages.error(
request,
_("This machine type change would create duplicated domains"),
)
return redirect(reverse("machines:index-machinetype"))
return form(
{"machinetypeform": machinetype, "action_name": _("Edit")},
"machines/machine.html",
request,
)
@login_required
@can_delete_set(MachineType)
def del_machinetype(request, instances):
"""View used to delete machines types."""
machinetype = DelMachineTypeForm(request.POST or None, instances=instances)
if machinetype.is_valid():
machinetype_dels = machinetype.cleaned_data["machinetypes"]
for machinetype_del in machinetype_dels:
try:
machinetype_del.delete()
messages.success(request, _("The machine type was deleted."))
except ProtectedError:
messages.error(
request,
(
_(
"The machine type %s is assigned to at least one"
" machine, you can't delete it."
)
% machinetype_del
),
)
return redirect(reverse("machines:index-machinetype"))
return form(
{"machinetypeform": machinetype, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_create(Extension)
def add_extension(request):
"""View used to create extensions."""
extension = ExtensionForm(request.POST or None)
if extension.is_valid():
extension.save()
messages.success(request, _("The extension was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"extensionform": extension, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Extension)
def edit_extension(request, extension_instance, **_kwargs):
"""View used to edit extensions."""
extension = ExtensionForm(request.POST or None, instance=extension_instance)
if extension.is_valid():
if extension.changed_data:
extension.save()
messages.success(request, _("The extension was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"extensionform": extension, "action_name": _("Edit")},
"machines/machine.html",
request,
)
@login_required
@can_delete_set(Extension)
def del_extension(request, instances):
"""View used to delete extensions."""
extension = DelExtensionForm(request.POST or None, instances=instances)
if extension.is_valid():
extension_dels = extension.cleaned_data["extensions"]
for extension_del in extension_dels:
try:
extension_del.delete()
messages.success(request, _("The extension was deleted."))
except ProtectedError as e:
messages.error(
request,
(
_(
"The extension %s is assigned to following %s : %s"
", you can't delete it."
)
% (
extension_del,
str(e.protected_objects.model._meta.verbose_name_plural),
",".join(
map(
lambda x: str(x["name"]),
e.protected_objects.values("name").iterator(),
)
),
)
),
)
return redirect(reverse("machines:index-extension"))
return form(
{"extensionform": extension, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_create(SOA)
def add_soa(request):
"""View used to create SOA records."""
soa = SOAForm(request.POST or None)
if soa.is_valid():
soa.save()
messages.success(request, _("The SOA record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"soaform": soa, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(SOA)
def edit_soa(request, soa_instance, **_kwargs):
"""View used to edit SOA records."""
soa = SOAForm(request.POST or None, instance=soa_instance)
if soa.is_valid():
if soa.changed_data:
soa.save()
messages.success(request, _("The SOA record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"soaform": soa, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(SOA)
def del_soa(request, instances):
"""View used to delete SOA records."""
soa = DelSOAForm(request.POST or None, instances=instances)
if soa.is_valid():
soa_dels = soa.cleaned_data["soa"]
for soa_del in soa_dels:
try:
soa_del.delete()
messages.success(request, _("The SOA record was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the SOA record %s can't be deleted.") % soa_del)
)
return redirect(reverse("machines:index-extension"))
return form(
{"soaform": soa, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Mx)
def add_mx(request):
"""View used to create MX records."""
mx = MxForm(request.POST or None)
if mx.is_valid():
mx.save()
messages.success(request, _("The MX record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"mxform": mx, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Mx)
def edit_mx(request, mx_instance, **_kwargs):
"""View used to edit MX records."""
mx = MxForm(request.POST or None, instance=mx_instance)
if mx.is_valid():
if mx.changed_data:
mx.save()
messages.success(request, _("The MX record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"mxform": mx, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Mx)
def del_mx(request, instances):
"""View used to delete MX records."""
mx = DelMxForm(request.POST or None, instances=instances)
if mx.is_valid():
mx_dels = mx.cleaned_data["mx"]
for mx_del in mx_dels:
try:
mx_del.delete()
messages.success(request, _("The MX record was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the MX record %s can't be deleted.") % mx_del)
)
return redirect(reverse("machines:index-extension"))
return form(
{"mxform": mx, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Ns)
def add_ns(request):
"""View used to create NS records."""
ns = NsForm(request.POST or None)
if ns.is_valid():
ns.save()
messages.success(request, _("The NS record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"nsform": ns, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Ns)
def edit_ns(request, ns_instance, **_kwargs):
"""View used to edit NS records."""
ns = NsForm(request.POST or None, instance=ns_instance)
if ns.is_valid():
if ns.changed_data:
ns.save()
messages.success(request, _("The NS record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"nsform": ns, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Ns)
def del_ns(request, instances):
"""View used to delete NS records."""
nss = DelNsForm(request.POST or None, instances=instances)
if nss.is_valid():
ns_dels = nss.cleaned_data["nss"]
for ns_del in ns_dels:
try:
ns_del.delete()
messages.success(request, _("The NS record was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the NS record %s can't be deleted.") % ns_del)
)
return redirect(reverse("machines:index-extension"))
return form(
{"nsform": nss, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(DName)
def add_dname(request):
"""View used to create DNAME records."""
dname = DNameForm(request.POST or None)
if dname.is_valid():
dname.save()
messages.success(request, _("The DNAME record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"dnameform": dname, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(DName)
def edit_dname(request, dname_instance, **_kwargs):
"""View used to edit DNAME records."""
dname = DNameForm(request.POST or None, instance=dname_instance)
if dname.is_valid():
if dname.changed_data:
dname.save()
messages.success(request, _("The DNAME record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"dnameform": dname, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(DName)
def del_dname(request, instances):
"""View used to delete DNAME records."""
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()
messages.success(request, _("The DNAME record was deleted."))
except ProtectedError:
messages.error(
request,
_("Error: the DNAME record %s can't be deleted.") % dname_del,
)
return redirect(reverse("machines:index-extension"))
return form(
{"dnameform": dname, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_create(Txt)
def add_txt(request):
"""View used to create TXT records."""
txt = TxtForm(request.POST or None)
if txt.is_valid():
txt.save()
messages.success(request, _("The TXT record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"txtform": txt, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Txt)
def edit_txt(request, txt_instance, **_kwargs):
"""View used to edit TXT records."""
txt = TxtForm(request.POST or None, instance=txt_instance)
if txt.is_valid():
if txt.changed_data:
txt.save()
messages.success(request, _("The TXT record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"txtform": txt, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Txt)
def del_txt(request, instances):
"""View used to delete TXT records."""
txt = DelTxtForm(request.POST or None, instances=instances)
if txt.is_valid():
txt_dels = txt.cleaned_data["txt"]
for txt_del in txt_dels:
try:
txt_del.delete()
messages.success(request, _("The TXT record was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the TXT record %s can't be deleted.") % txt_del)
)
return redirect(reverse("machines:index-extension"))
return form(
{"txtform": txt, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Srv)
def add_srv(request):
"""View used to create SRV records."""
srv = SrvForm(request.POST or None)
if srv.is_valid():
srv.save()
messages.success(request, _("The SRV record was created."))
return redirect(reverse("machines:index-extension"))
return form(
{"srvform": srv, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Srv)
def edit_srv(request, srv_instance, **_kwargs):
"""View used to edit SRV records."""
srv = SrvForm(request.POST or None, instance=srv_instance)
if srv.is_valid():
if srv.changed_data:
srv.save()
messages.success(request, _("The SRV record was edited."))
return redirect(reverse("machines:index-extension"))
return form(
{"srvform": srv, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Srv)
def del_srv(request, instances):
"""View used to delete SRV records."""
srv = DelSrvForm(request.POST or None, instances=instances)
if srv.is_valid():
srv_dels = srv.cleaned_data["srv"]
for srv_del in srv_dels:
try:
srv_del.delete()
messages.success(request, _("The SRV record was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the SRV record %s can't be deleted.") % srv_del)
)
return redirect(reverse("machines:index-extension"))
return form(
{"srvform": srv, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Domain)
@can_edit(Interface)
def add_alias(request, interface, interfaceid):
"""View used to create aliases."""
alias = AliasForm(request.POST or None, user=request.user)
if alias.is_valid():
alias = alias.save(commit=False)
alias.cname = interface.domain
alias.save()
messages.success(request, _("The alias was created."))
return redirect(
reverse("machines:index-alias", kwargs={"interfaceid": str(interfaceid)})
)
return form(
{"aliasform": alias, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Domain)
def edit_alias(request, domain_instance, **_kwargs):
"""View used to edit aliases records."""
alias = AliasForm(request.POST or None, instance=domain_instance, user=request.user)
if alias.is_valid():
if alias.changed_data:
domain_instance = alias.save()
messages.success(request, _("The alias was edited."))
return redirect(
reverse(
"machines:index-alias",
kwargs={"interfaceid": str(domain_instance.cname.interface_parent.id)},
)
)
return form(
{"aliasform": alias, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_edit(Interface)
def del_alias(request, interface, interfaceid):
"""View used to delete aliases records."""
alias = DelAliasForm(request.POST or None, interface=interface)
if alias.is_valid():
alias_dels = alias.cleaned_data["alias"]
for alias_del in alias_dels:
try:
alias_del.delete()
messages.success(request, _("The alias %s was deleted.") % alias_del)
except ProtectedError:
messages.error(
request, (_("Error: the alias %s can't be deleted.") % alias_del)
)
return redirect(
reverse("machines:index-alias", kwargs={"interfaceid": str(interfaceid)})
)
return form(
{"aliasform": alias, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_create(Role)
def add_role(request):
"""View used to create roles."""
role = RoleForm(request.POST or None)
if role.is_valid():
role.save()
messages.success(request, _("The role was created."))
return redirect(reverse("machines:index-role"))
return form(
{"roleform": role, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Role)
def edit_role(request, role_instance, **_kwargs):
"""View used to edit roles."""
role = RoleForm(request.POST or None, instance=role_instance)
if role.is_valid():
if role.changed_data:
role.save()
messages.success(request, _("The role was edited."))
return redirect(reverse("machines:index-role"))
return form(
{"roleform": role, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Role)
def del_role(request, instances):
"""View used to delete roles."""
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, _("The role was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the role %s can't be deleted.") % role_del)
)
return redirect(reverse("machines:index-role"))
return form(
{"roleform": role, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Service)
def add_service(request):
"""View used to create services."""
service = ServiceForm(request.POST or None)
if service.is_valid():
service.save()
messages.success(request, _("The service was created."))
return redirect(reverse("machines:index-service"))
return form(
{"serviceform": service, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Service)
def edit_service(request, service_instance, **_kwargs):
"""View used to edit services."""
service = ServiceForm(request.POST or None, instance=service_instance)
if service.is_valid():
if service.changed_data:
service.save()
messages.success(request, _("The service was edited."))
return redirect(reverse("machines:index-service"))
return form(
{"serviceform": service, "action_name": _("Edit")},
"machines/machine.html",
request,
)
@login_required
@can_delete_set(Service)
def del_service(request, instances):
"""View used to delete services."""
service = DelServiceForm(request.POST or None, instances=instances)
if service.is_valid():
service_dels = service.cleaned_data["service"]
for service_del in service_dels:
try:
service_del.delete()
messages.success(request, _("The service was deleted."))
except ProtectedError:
messages.error(
request,
(_("Error: the service %s can't be deleted.") % service_del),
)
return redirect(reverse("machines:index-service"))
return form(
{"serviceform": service, "action_name": _("Delete")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Service)
def regen_service(request, service, **_kwargs):
"""Ask for a regen of the service"""
regen(service)
return index_service(request)
@login_required
@can_create(Vlan)
def add_vlan(request):
"""View used to create VLANs."""
vlan = VlanForm(request.POST or None)
if vlan.is_valid():
vlan.save()
messages.success(request, _("The VLAN was created."))
return redirect(reverse("machines:index-vlan"))
return form(
{"vlanform": vlan, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Vlan)
def edit_vlan(request, vlan_instance, **_kwargs):
"""View used to edit VLANs."""
vlan = VlanForm(request.POST or None, instance=vlan_instance)
if vlan.is_valid():
if vlan.changed_data:
vlan.save()
messages.success(request, _("The VLAN was edited."))
return redirect(reverse("machines:index-vlan"))
return form(
{"vlanform": vlan, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Vlan)
def del_vlan(request, instances):
"""View used to delete VLANs."""
vlan = DelVlanForm(request.POST or None, instances=instances)
if vlan.is_valid():
vlan_dels = vlan.cleaned_data["vlan"]
for vlan_del in vlan_dels:
try:
vlan_del.delete()
messages.success(request, _("The VLAN was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the VLAN %s can't be deleted.") % vlan_del)
)
return redirect(reverse("machines:index-vlan"))
return form(
{"vlanform": vlan, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_create(Nas)
def add_nas(request):
"""View used to create NAS devices."""
nas = NasForm(request.POST or None)
if nas.is_valid():
nas.save()
messages.success(request, _("The NAS device was created."))
return redirect(reverse("machines:index-nas"))
return form(
{"nasform": nas, "action_name": _("Add")},
"machines/machine.html",
request,
)
@login_required
@can_edit(Nas)
def edit_nas(request, nas_instance, **_kwargs):
"""View used to edit NAS devices."""
nas = NasForm(request.POST or None, instance=nas_instance)
if nas.is_valid():
if nas.changed_data:
nas.save()
messages.success(request, _("The NAS device was edited."))
return redirect(reverse("machines:index-nas"))
return form(
{"nasform": nas, "action_name": _("Edit")}, "machines/machine.html", request
)
@login_required
@can_delete_set(Nas)
def del_nas(request, instances):
"""View used to delete NAS devices."""
nas = DelNasForm(request.POST or None, instances=instances)
if nas.is_valid():
nas_dels = nas.cleaned_data["nas"]
for nas_del in nas_dels:
try:
nas_del.delete()
messages.success(request, _("The NAS device was deleted."))
except ProtectedError:
messages.error(
request, (_("Error: the NAS device %s can't be deleted.") % nas_del)
)
return redirect(reverse("machines:index-nas"))
return form(
{"nasform": nas, "action_name": _("Delete")}, "machines/machine.html", request
)
@login_required
@can_view_all(Machine)
def index(request):
"""The home view for this app. Displays the list of registered
machines in Re2o."""
pagination_large_number = GeneralOption.get_cached_value("pagination_large_number")
machines_list = (
Machine.objects.select_related("user")
.prefetch_related("interface_set__domain__extension")
.prefetch_related("interface_set__ipv4__ip_type")
.prefetch_related("interface_set__machine_type__ip_type__extension")
.prefetch_related("interface_set__domain__related_domain__extension")
.prefetch_related("interface_set__ipv6list")
)
machines_list = SortTable.sort(
machines_list,
request.GET.get("col"),
request.GET.get("order"),
SortTable.MACHINES_INDEX,
)
machines_list = re2o_paginator(request, machines_list, pagination_large_number)
return render(request, "machines/index.html", {"machines_list": machines_list})
# Canonic view for displaying machines in users's profil
def aff_profil(request, user):
"""View used to display the machines on a user's profile."""
machines = (
Machine.objects.filter(user=user)
.select_related("user")
.prefetch_related("interface_set__domain__extension")
.prefetch_related("interface_set__ipv4__ip_type__extension")
.prefetch_related("interface_set__machine_type")
.prefetch_related("interface_set__domain__related_domain__extension")
)
machines = SortTable.sort(
machines,
request.GET.get("col"),
request.GET.get("order"),
SortTable.MACHINES_INDEX,
)
nb_machines = machines.count()
pagination_large_number = GeneralOption.get_cached_value("pagination_large_number")
machines = re2o_paginator(request, machines, pagination_large_number)
context = {
"users": user,
"machines_list": machines,
"nb_machines": nb_machines,
}
return render_to_string(
"machines/aff_profil.html", context=context, request=request, using=None
)
@login_required
@can_view_all(IpType)
def index_iptype(request):
"""View used to display the list of existing types of IP."""
pagination_large_number = GeneralOption.get_cached_value("pagination_large_number")
iptype_list = (
IpType.objects.select_related("extension")
.select_related("vlan")
.order_by("name")
)
iptype_list = re2o_paginator(request, iptype_list, pagination_large_number)
return render(request, "machines/index_iptype.html", {"iptype_list": iptype_list})
@login_required
@can_view_all(Vlan)
def index_vlan(request):
"""View used to display the list of existing VLANs."""
vlan_list = Vlan.objects.prefetch_related("iptype_set").order_by("vlan_id")
return render(request, "machines/index_vlan.html", {"vlan_list": vlan_list})
@login_required
@can_view_all(MachineType)
def index_machinetype(request):
"""View used to display the list of existing types of machines."""
machinetype_list = MachineType.objects.select_related("ip_type").order_by("name")
return render(
request,
"machines/index_machinetype.html",
{"machinetype_list": machinetype_list},
)
@login_required
@can_view_all(Nas)
def index_nas(request):
"""View used to display the list of existing NAS devices."""
nas_list = (
Nas.objects.select_related("machine_type")
.select_related("nas_type")
.order_by("name")
)
return render(request, "machines/index_nas.html", {"nas_list": nas_list})
@login_required
@can_view_all(SOA, Mx, Ns, Txt, DName, Srv, Extension)
def index_extension(request):
"""View used to display the list of existing extensions, the list of
existing SOA records, the list of existing MX records , the list of
existing NS records, the list of existing TXT records and the list of
existing SRV records.
"""
extension_list = (
Extension.objects.select_related("origin")
.select_related("soa")
.order_by("name")
)
soa_list = SOA.objects.order_by("name")
mx_list = (
Mx.objects.order_by("zone")
.select_related("zone")
.select_related("name__extension")
)
ns_list = (
Ns.objects.order_by("zone")
.select_related("zone")
.select_related("ns__extension")
)
txt_list = Txt.objects.all().select_related("zone")
dname_list = DName.objects.all().select_related("zone")
srv_list = (
Srv.objects.all()
.select_related("extension")
.select_related("target__extension")
)
return render(
request,
"machines/index_extension.html",
{
"extension_list": extension_list,
"soa_list": soa_list,
"mx_list": mx_list,
"ns_list": ns_list,
"txt_list": txt_list,
"dname_list": dname_list,
"srv_list": srv_list,
},
)
@login_required
@can_edit(Interface)
def index_alias(request, interface, interfaceid):
"""View used to display the list of existing aliases of an interface."""
alias_list = Domain.objects.filter(
cname=Domain.objects.filter(interface_parent=interface)
).order_by("name")
return render(
request,
"machines/index_alias.html",
{"alias_list": alias_list, "interface_id": interfaceid},
)
@login_required
@can_view(Machine)
def index_sshfp(request, machine, machineid):
"""View used to display the list of existing SSHFP records associated
with a machine."""
sshfp_list = SshFp.objects.filter(machine=machine)
return render(
request,
"machines/index_sshfp.html",
{"sshfp_list": sshfp_list, "machine_id": machineid},
)
@login_required
@can_view(Interface)
def index_ipv6(request, interface, interfaceid):
"""View used to display the list of existing IPv6 of an interface."""
ipv6_list = Ipv6List.objects.filter(interface=interface)
return render(
request,
"machines/index_ipv6.html",
{"ipv6_list": ipv6_list, "interface_id": 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):
"""View used to display the list of existing services."""
service_list = Service.objects.prefetch_related(
"service_link_set__server__domain__extension"
).all()
servers_list = (
Service_link.objects.select_related("server__domain__extension")
.select_related("service")
.all()
)
return render(
request,
"machines/index_service.html",
{"service_list": service_list, "servers_list": servers_list},
)
@login_required
@can_view_all(OuverturePortList)
def index_portlist(request):
"""View used to display the list of existing port policies."""
port_list = (
OuverturePortList.objects.prefetch_related("ouvertureport_set")
.prefetch_related("interface_set__domain__extension")
.prefetch_related("interface_set__machine__user")
.order_by("name")
)
return render(request, "machines/index_portlist.html", {"port_list": port_list})
@login_required
@can_edit(OuverturePortList)
def edit_portlist(request, ouvertureportlist_instance, **_kwargs):
"""View used to edit port policies."""
port_list = EditOuverturePortListForm(
request.POST or None, instance=ouvertureportlist_instance
)
port_formset = modelformset_factory(
OuverturePort,
fields=("begin", "end", "protocole", "io"),
extra=0,
can_delete=True,
min_num=1,
validate_min=True,
)(request.POST or None, queryset=ouvertureportlist_instance.ouvertureport_set.all())
if port_list.is_valid() and port_formset.is_valid():
if port_list.changed_data:
pl = port_list.save()
else:
pl = ouvertureportlist_instance
instances = port_formset.save(commit=False)
for to_delete in port_formset.deleted_objects:
to_delete.delete()
for port in instances:
port.port_list = pl
port.save()
messages.success(request, _("The ports list was edited."))
return redirect(reverse("machines:index-portlist"))
return form(
{"port_list": port_list, "ports": port_formset},
"machines/edit_portlist.html",
request,
)
@login_required
@can_delete(OuverturePortList)
def del_portlist(request, port_list_instance, **_kwargs):
"""View used to delete port policies."""
port_list_instance.delete()
messages.success(request, _("The ports list was deleted."))
return redirect(reverse("machines:index-portlist"))
@login_required
@can_create(OuverturePortList)
def add_portlist(request):
"""View used to create port policies."""
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,
)(request.POST or None, queryset=OuverturePort.objects.none())
if port_list.is_valid() and port_formset.is_valid():
pl = port_list.save()
instances = port_formset.save(commit=False)
for to_delete in port_formset.deleted_objects:
to_delete.delete()
for port in instances:
port.port_list = pl
port.save()
messages.success(request, _("The ports list was created."))
return redirect(reverse("machines:index-portlist"))
return form(
{"port_list": port_list, "ports": port_formset},
"machines/edit_portlist.html",
request,
)
@login_required
@can_create(OuverturePort)
@can_edit(Interface)
def configure_ports(request, interface_instance, **_kwargs):
"""View to display the list of configured port policies for an
interface.
"""
if not interface_instance.may_have_port_open():
messages.error(
request,
(
_(
"Warning: the IP address is not public, the opening won't"
" have any effect in v4."
)
),
)
interface = EditOuverturePortConfigForm(
request.POST or None, instance=interface_instance
)
if interface.is_valid():
if interface.changed_data:
interface.save()
messages.success(request, _("The ports configuration was edited."))
return redirect(reverse("machines:index"))
return form(
{"interfaceform": interface, "action_name": _("Edit")},
"machines/machine.html",
request,
)