8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-25 04:43:10 +00:00
re2o/machines/forms.py

744 lines
24 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 © 2017 Gabriel Détraz
# Copyright © 2017 Lara Kermarec
# Copyright © 2017 Augustin Lemesle
# Copyright © 2017 Maël Kervella
#
# 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.
"""
Forms to create, edit and delete:
* machines
* interfaces
* domains (machine names)
* aliases (CNAME)
* services (DHCP, DNS...)
* NS records (DNS server)
* MX records (mail serveur)
* open ports and ports opening for interfaces
"""
from __future__ import unicode_literals
from django import forms
from django.forms import Form, ModelForm
from django.utils.translation import ugettext_lazy as _
from re2o.field_permissions import FieldPermissionFormMixin
from re2o.mixins import FormRevMixin
from re2o.widgets import (AutocompleteModelWidget,
AutocompleteMultipleModelWidget)
from .models import (SOA, DName, Domain, Extension, Interface, IpList, IpType,
Ipv6List, Machine, MachineType, Mx, Nas, Ns,
OuverturePortList, Role, Service, Srv, SshFp, Txt, Vlan)
class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Form used to edit a machine."""
class Meta:
model = Machine
fields = "__all__"
widgets = {"user": AutocompleteModelWidget(url="/users/user-autocomplete")}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditMachineForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["name"].label = _("Machine name")
class NewMachineForm(EditMachineForm):
"""Form used to create a machine."""
class Meta(EditMachineForm.Meta):
fields = ["name"]
class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Form used to edit an interface."""
class Meta:
model = Interface
fields = ["machine", "machine_type", "ipv4", "mac_address", "details"]
widgets = {
"machine": AutocompleteModelWidget(url="/machines/machine-autocomplete"),
"machine_type": AutocompleteModelWidget(
url="/machines/machinetype-autocomplete"
),
"ipv4": AutocompleteModelWidget(
url="/machines/iplist-autocomplete",
forward=["machine_type"],
attrs={
"data-placeholder": "Automatic assigment. Type to choose specific ip."
},
),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
user = kwargs.get("user")
super(EditInterfaceForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["mac_address"].label = _("MAC address")
self.fields["machine_type"].label = _("Machine type")
self.fields["machine_type"].empty_label = _("Select a machine type")
if "ipv4" in self.fields:
self.fields["ipv4"].empty_label = _("Automatic IPv4 assignment")
self.fields["ipv4"].queryset = IpList.objects.filter(interface__isnull=True)
can_use_all_iptype, _reason, _permissions = IpType.can_use_all(user)
if not can_use_all_iptype:
self.fields["ipv4"].queryset = IpList.objects.filter(
interface__isnull=True
).filter(ip_type__in=IpType.objects.filter(need_infra=False))
else:
self.fields["ipv4"].queryset = IpList.objects.filter(
interface__isnull=True
)
# Add it's own address
self.fields["ipv4"].queryset |= IpList.objects.filter(
interface=self.instance
)
if "machine" in self.fields:
self.fields["machine"].queryset = Machine.objects.all().select_related(
"user"
)
can_use_all_machinetype, _reason, _permissions = MachineType.can_use_all(user)
if not can_use_all_machinetype:
self.fields["machine_type"].queryset = MachineType.objects.filter(
ip_type__in=IpType.objects.filter(need_infra=False)
)
class AddInterfaceForm(EditInterfaceForm):
"""Form used to add an interface to a machine."""
class Meta(EditInterfaceForm.Meta):
fields = ["machine_type", "ipv4", "mac_address", "details"]
class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Form used to add and edit an alias (CNAME)."""
class Meta:
model = Domain
fields = ["name", "extension", "ttl"]
widgets = {
"extension": AutocompleteModelWidget(url="/machines/extension-autocomplete")
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
user = kwargs["user"]
super(AliasForm, self).__init__(*args, prefix=prefix, **kwargs)
can_use_all, _reason, _permissions = Extension.can_use_all(user)
if not can_use_all:
self.fields["extension"].queryset = Extension.objects.filter(
need_infra=False
)
class DomainForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Form used to add and edit a domain record, related to an
interface.
"""
class Meta:
model = Domain
fields = ["name", "ttl"]
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(DomainForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelAliasForm(FormRevMixin, Form):
"""Form used to delete one or several aliases."""
alias = forms.ModelMultipleChoiceField(
queryset=Domain.objects.all(),
label=_("Current aliases"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
interface = kwargs.pop("interface")
super(DelAliasForm, self).__init__(*args, **kwargs)
self.fields["alias"].queryset = Domain.objects.filter(
cname__in=Domain.objects.filter(interface_parent=interface)
)
class MachineTypeForm(FormRevMixin, ModelForm):
"""Form used to add and edit a machine type, related to an IP type."""
class Meta:
model = MachineType
fields = ["name", "ip_type"]
widgets = {
"ip_type": AutocompleteModelWidget(url="/machines/iptype-autocomplete")
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(MachineTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["name"].label = _("Machine type to add")
self.fields["ip_type"].label = _("Related IP type")
class DelMachineTypeForm(FormRevMixin, Form):
"""Form used to delete one or several machines types."""
machinetypes = forms.ModelMultipleChoiceField(
queryset=MachineType.objects.none(),
label=_("Current machine types"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelMachineTypeForm, self).__init__(*args, **kwargs)
if instances:
self.fields["machinetypes"].queryset = instances
else:
self.fields["machinetypes"].queryset = MachineType.objects.all()
class IpTypeForm(FormRevMixin, ModelForm):
"""Form used to add an IP type. The start and stop IP addresses cannot
be changed afterwards.
"""
class Meta:
model = IpType
fields = "__all__"
widgets = {
"vlan": AutocompleteModelWidget(url="/machines/vlan-autocomplete"),
"extension": AutocompleteModelWidget(
url="/machines/extension-autocomplete"
),
"ouverture_ports": AutocompleteModelWidget(
url="/machines/ouvertureportlist-autocomplete"
),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(IpTypeForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["name"].label = _("IP type to add")
class EditIpTypeForm(IpTypeForm):
"""Form used to edit an IP type. The start and stop IP addresses cannot
be changed.
"""
class Meta(IpTypeForm.Meta):
fields = [
"extension",
"name",
"need_infra",
"domaine_ip_network",
"domaine_ip_netmask",
"prefix_v6",
"prefix_v6_length",
"vlan",
"reverse_v4",
"reverse_v6",
"ouverture_ports",
]
class DelIpTypeForm(FormRevMixin, Form):
"""Form used to delete one or several IP types."""
iptypes = forms.ModelMultipleChoiceField(
queryset=IpType.objects.none(),
label=_("Current IP types"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelIpTypeForm, self).__init__(*args, **kwargs)
if instances:
self.fields["iptypes"].queryset = instances
else:
self.fields["iptypes"].queryset = IpType.objects.all()
class ExtensionForm(FormRevMixin, ModelForm):
"""Form used to add and edit extensions."""
class Meta:
model = Extension
fields = "__all__"
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(ExtensionForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["name"].label = _("Extension to add")
self.fields["origin"].label = _("A record origin")
self.fields["origin_v6"].label = _("AAAA record origin")
self.fields["soa"].label = _("SOA record to use")
self.fields["dnssec"].label = _("Sign with DNSSEC")
class DelExtensionForm(FormRevMixin, Form):
"""Form used to delete one or several extensions."""
extensions = forms.ModelMultipleChoiceField(
queryset=Extension.objects.none(),
label=_("Current extensions"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelExtensionForm, self).__init__(*args, **kwargs)
if instances:
self.fields["extensions"].queryset = instances
else:
self.fields["extensions"].queryset = Extension.objects.all()
class Ipv6ListForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
"""Form used to manage lists of IPv6 addresses."""
class Meta:
model = Ipv6List
fields = ["ipv6", "slaac_ip", "active"]
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(Ipv6ListForm, self).__init__(*args, prefix=prefix, **kwargs)
class SOAForm(FormRevMixin, ModelForm):
"""Form used to add and edit SOA records."""
class Meta:
model = SOA
fields = "__all__"
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(SOAForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelSOAForm(FormRevMixin, Form):
"""Form used to delete one or several SOA records."""
soa = forms.ModelMultipleChoiceField(
queryset=SOA.objects.none(),
label=_("Current SOA records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelSOAForm, self).__init__(*args, **kwargs)
if instances:
self.fields["soa"].queryset = instances
else:
self.fields["soa"].queryset = SOA.objects.all()
class MxForm(FormRevMixin, ModelForm):
"""Form used to add and edit MX records."""
class Meta:
model = Mx
fields = ["zone", "priority", "name", "ttl"]
widgets = {
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
"name": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(MxForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["name"].queryset = Domain.objects.exclude(
interface_parent=None
).select_related("extension")
class DelMxForm(FormRevMixin, Form):
"""Form used to delete one or several MX records."""
mx = forms.ModelMultipleChoiceField(
queryset=Mx.objects.none(),
label=_("Current MX records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelMxForm, self).__init__(*args, **kwargs)
if instances:
self.fields["mx"].queryset = instances
else:
self.fields["mx"].queryset = Mx.objects.all()
class NsForm(FormRevMixin, ModelForm):
"""Form used to add and edit NS records. Only interface names are
available because CNAME aliases should not be used in the records.
"""
class Meta:
model = Ns
fields = ["zone", "ns", "ttl"]
widgets = {
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
"ns": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(NsForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["ns"].queryset = Domain.objects.exclude(
interface_parent=None
).select_related("extension")
class DelNsForm(FormRevMixin, Form):
"""Form used to delete one or several NS records."""
nss = forms.ModelMultipleChoiceField(
queryset=Ns.objects.none(),
label=_("Current NS records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelNsForm, self).__init__(*args, **kwargs)
if instances:
self.fields["nss"].queryset = instances
else:
self.fields["nss"].queryset = Ns.objects.all()
class TxtForm(FormRevMixin, ModelForm):
"""Form used to add and edit TXT records."""
class Meta:
model = Txt
fields = "__all__"
widgets = {
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete")
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(TxtForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelTxtForm(FormRevMixin, Form):
"""Form used to delete one or several TXT records."""
txt = forms.ModelMultipleChoiceField(
queryset=Txt.objects.none(),
label=_("Current TXT records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelTxtForm, self).__init__(*args, **kwargs)
if instances:
self.fields["txt"].queryset = instances
else:
self.fields["txt"].queryset = Txt.objects.all()
class DNameForm(FormRevMixin, ModelForm):
"""Form used to add and edit DNAME records."""
class Meta:
model = DName
fields = "__all__"
widgets = {
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete")
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(DNameForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelDNameForm(FormRevMixin, Form):
"""Form used to delete one or several DNAME records."""
dnames = forms.ModelMultipleChoiceField(
queryset=Txt.objects.none(),
label=_("Current DNAME records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelDNameForm, self).__init__(*args, **kwargs)
if instances:
self.fields["dnames"].queryset = instances
else:
self.fields["dnames"].queryset = DName.objects.all()
class SrvForm(FormRevMixin, ModelForm):
"""Form used to add and edit SRV records."""
class Meta:
model = Srv
fields = "__all__"
widgets = {
"extension": AutocompleteModelWidget(
url="/machines/extension-autocomplete"
),
"target": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(SrvForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelSrvForm(FormRevMixin, Form):
"""Form used to delete one or several SRV records."""
srv = forms.ModelMultipleChoiceField(
queryset=Srv.objects.none(),
label=_("Current SRV records"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelSrvForm, self).__init__(*args, **kwargs)
if instances:
self.fields["srv"].queryset = instances
else:
self.fields["srv"].queryset = Srv.objects.all()
class NasForm(FormRevMixin, ModelForm):
"""Form used to create and edit NAS devices."""
class Meta:
model = Nas
fields = "__all__"
widgets = {
"nas_type": AutocompleteModelWidget(
url="/machines/machinetype-autocomplete"
),
"machine_type": AutocompleteModelWidget(
url="/machines/machinetype-autocomplete"
),
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(NasForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelNasForm(FormRevMixin, Form):
"""Form used to delete one or several NAS devices."""
nas = forms.ModelMultipleChoiceField(
queryset=Nas.objects.none(),
label=_("Current NAS devices"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelNasForm, self).__init__(*args, **kwargs)
if instances:
self.fields["nas"].queryset = instances
else:
self.fields["nas"].queryset = Nas.objects.all()
class RoleForm(FormRevMixin, ModelForm):
"""Form used to add and edit roles."""
class Meta:
model = Role
fields = "__all__"
widgets = {
"servers": AutocompleteMultipleModelWidget(
url="/machines/interface-autocomplete"
)
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(RoleForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["servers"].queryset = Interface.objects.all().select_related(
"domain__extension"
)
class DelRoleForm(FormRevMixin, Form):
"""Form used to delete one or several roles."""
role = forms.ModelMultipleChoiceField(
queryset=Role.objects.none(),
label=_("Current roles"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelRoleForm, self).__init__(*args, **kwargs)
if instances:
self.fields["role"].queryset = instances
else:
self.fields["role"].queryset = Role.objects.all()
class ServiceForm(FormRevMixin, ModelForm):
"""Form to add and edit services (DHCP, DNS etc.)."""
class Meta:
model = Service
fields = "__all__"
widgets = {
"servers": AutocompleteMultipleModelWidget(
url="/machines/interface-autocomplete"
)
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(ServiceForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields["servers"].queryset = Interface.objects.all().select_related(
"domain__extension"
)
def save(self, commit=True):
# TODO : None of the parents of ServiceForm use the commit
# parameter in .save()
instance = super(ServiceForm, self).save(commit=False)
if commit:
instance.save()
instance.process_link(self.cleaned_data.get("servers"))
return instance
class DelServiceForm(FormRevMixin, Form):
"""Form used to delete one or several services."""
service = forms.ModelMultipleChoiceField(
queryset=Service.objects.none(),
label=_("Current services"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelServiceForm, self).__init__(*args, **kwargs)
if instances:
self.fields["service"].queryset = instances
else:
self.fields["service"].queryset = Service.objects.all()
class VlanForm(FormRevMixin, ModelForm):
"""Form used to add and edit VLANs."""
class Meta:
model = Vlan
fields = ["vlan_id", "name", "comment"]
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(VlanForm, self).__init__(*args, prefix=prefix, **kwargs)
class EditOptionVlanForm(FormRevMixin, ModelForm):
"""Form used to edit the options of a VLAN."""
class Meta:
model = Vlan
fields = ["dhcp_snooping", "dhcpv6_snooping", "arp_protect", "igmp", "mld"]
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditOptionVlanForm, self).__init__(*args, prefix=prefix, **kwargs)
class DelVlanForm(FormRevMixin, Form):
"""Form used to delete one or several VLANs."""
vlan = forms.ModelMultipleChoiceField(
queryset=Vlan.objects.none(),
label=_("Current VLANs"),
widget=forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
instances = kwargs.pop("instances", None)
super(DelVlanForm, self).__init__(*args, **kwargs)
if instances:
self.fields["vlan"].queryset = instances
else:
self.fields["vlan"].queryset = Vlan.objects.all()
class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
"""Form to edit the ports opening list of an interface."""
class Meta:
model = Interface
fields = ["port_lists"]
widgets = {
"port_lists": AutocompleteMultipleModelWidget(
url="/machines/ouvertureportlist-autocomplete"
)
}
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditOuverturePortConfigForm, self).__init__(
*args, prefix=prefix, **kwargs
)
class EditOuverturePortListForm(FormRevMixin, ModelForm):
"""Form used to add and edit ports opening lists."""
class Meta:
model = OuverturePortList
fields = "__all__"
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(EditOuverturePortListForm, self).__init__(*args, prefix=prefix, **kwargs)
class SshFpForm(FormRevMixin, ModelForm):
"""Form used to add and edit SSHFP records."""
class Meta:
model = SshFp
exclude = ("machine",)
def __init__(self, *args, **kwargs):
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
super(SshFpForm, self).__init__(*args, prefix=prefix, **kwargs)