# 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 # # 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 for the topologie app of re2o. The forms are used to: * create and delete switch ports, related to a switch. * create stacks and add switches to them (StackForm). * create, edit and delete a switch (NewSwitchForm, EditSwitchForm). """ from __future__ import unicode_literals from django import forms from django.forms import ModelForm from django.db.models import Prefetch from django.utils.translation import ugettext_lazy as _ from machines.models import Interface from machines.forms import EditMachineForm, NewMachineForm from re2o.mixins import FormRevMixin from re2o.widgets import ( AutocompleteModelWidget, AutocompleteMultipleModelWidget, ) from .models import ( Port, Switch, Room, Stack, ModelSwitch, ConstructorSwitch, AccessPoint, SwitchBay, Building, Dormitory, PortProfile, ModuleSwitch, ModuleOnSwitch, ) class PortForm(FormRevMixin, ModelForm): """Form used to manage a switch's port.""" class Meta: model = Port fields = "__all__" widgets = { "switch": AutocompleteModelWidget(url="/topologie/switch-autocomplete"), "room": AutocompleteModelWidget(url="/topologie/room-autocomplete"), "machine_interface": AutocompleteModelWidget( url="/machines/interface-autocomplete" ), "related": AutocompleteModelWidget(url="/topologie/port-autocomplete"), "custom_profile": AutocompleteModelWidget( url="/topologie/portprofile-autocomplete" ), } def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(PortForm, self).__init__(*args, prefix=prefix, **kwargs) class EditPortForm(FormRevMixin, ModelForm): """Form used to edit a switch's port: change in RADIUS or VLANs settings, assignement to a room, port or machine. A port is related to either a room, another port (uplink) or a machine (server or AP). """ class Meta(PortForm.Meta): fields = [ "room", "related", "machine_interface", "custom_profile", "state", "details", ] def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditPortForm, self).__init__(*args, prefix=prefix, **kwargs) self.fields[ "machine_interface" ].queryset = Interface.objects.all().select_related("domain__extension") self.fields["related"].queryset = Port.objects.all().prefetch_related( "switch__machine_ptr__interface_set__domain__extension" ) self.fields["room"].queryset = Room.objects.all().select_related( "building__dormitory" ) class AddPortForm(FormRevMixin, ModelForm): """Form used to add a switch's port. See EditPortForm.""" class Meta(PortForm.Meta): fields = [ "port", "room", "machine_interface", "related", "custom_profile", "state", "details", ] def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(AddPortForm, self).__init__(*args, prefix=prefix, **kwargs) self.fields[ "machine_interface" ].queryset = Interface.objects.all().select_related("domain__extension") self.fields["related"].queryset = Port.objects.all().prefetch_related( Prefetch( "switch__interface_set", queryset=( Interface.objects.select_related( "ipv4__ip_type__extension" ).select_related("domain__extension") ), ) ) class StackForm(FormRevMixin, ModelForm): """Form used to create and edit stacks.""" class Meta: model = Stack fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(StackForm, self).__init__(*args, prefix=prefix, **kwargs) class AddAccessPointForm(NewMachineForm): """Form used to create access points.""" class Meta: model = AccessPoint fields = ["location", "name"] class EditAccessPointForm(EditMachineForm): """Form used to edit access points.""" class Meta(EditMachineForm.Meta): model = AccessPoint fields = "__all__" class EditSwitchForm(EditMachineForm): """Form used to edit switches.""" class Meta(EditMachineForm.Meta): model = Switch fields = "__all__" widgets = { "switchbay": AutocompleteModelWidget( url="/topologie/switchbay-autocomplete" ), "user": AutocompleteModelWidget(url="/users/user-autocomplete"), } class NewSwitchForm(NewMachineForm): """Form used to create a switch.""" class Meta(EditSwitchForm.Meta): fields = ["name", "switchbay", "number", "stack", "stack_member_id"] class EditRoomForm(FormRevMixin, ModelForm): """Form used to edit a room.""" class Meta: model = Room fields = "__all__" widgets = { "building": AutocompleteModelWidget(url="/topologie/building-autocomplete") } def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditRoomForm, self).__init__(*args, prefix=prefix, **kwargs) class CreatePortsForm(forms.Form): """Form used to create switch ports lists.""" begin = forms.IntegerField(label=_("Start:"), min_value=0) end = forms.IntegerField(label=_("End:"), min_value=0) class EditModelSwitchForm(FormRevMixin, ModelForm): """Form used to edit switch models.""" members = forms.ModelMultipleChoiceField( Switch.objects.all(), widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), required=False, ) class Meta: model = ModelSwitch fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditModelSwitchForm, self).__init__(*args, prefix=prefix, **kwargs) instance = kwargs.get("instance", None) if instance: self.initial["members"] = Switch.objects.filter(model=instance) def save(self, commit=True): instance = super().save(commit) instance.switch_set = self.cleaned_data["members"] return instance class EditConstructorSwitchForm(FormRevMixin, ModelForm): """Form used to edit switch constructors.""" class Meta: model = ConstructorSwitch fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditConstructorSwitchForm, self).__init__(*args, prefix=prefix, **kwargs) class EditSwitchBayForm(FormRevMixin, ModelForm): """Form used to edit switch bays.""" members = forms.ModelMultipleChoiceField( Switch.objects.all(), required=False, widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), ) class Meta: model = SwitchBay fields = "__all__" widgets = { "building": AutocompleteModelWidget(url="/topologie/building-autocomplete") } def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditSwitchBayForm, self).__init__(*args, prefix=prefix, **kwargs) instance = kwargs.get("instance", None) if instance: self.initial["members"] = Switch.objects.filter(switchbay=instance) def save(self, commit=True): instance = super().save(commit) instance.switch_set = self.cleaned_data["members"] return instance class EditBuildingForm(FormRevMixin, ModelForm): """Form used to edit buildings.""" class Meta: model = Building fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditBuildingForm, self).__init__(*args, prefix=prefix, **kwargs) class EditDormitoryForm(FormRevMixin, ModelForm): """Form used to edit dormitories.""" class Meta: model = Dormitory fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditDormitoryForm, self).__init__(*args, prefix=prefix, **kwargs) class EditPortProfileForm(FormRevMixin, ModelForm): """Form used to edit port profiles.""" class Meta: model = PortProfile fields = "__all__" widgets = { "vlan_tagged": AutocompleteMultipleModelWidget( url="/machines/vlan-autocomplete" ), "vlan_untagged": AutocompleteModelWidget(url="/machines/vlan-autocomplete"), } def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditPortProfileForm, self).__init__(*args, prefix=prefix, **kwargs) class EditModuleForm(FormRevMixin, ModelForm): """Form used to add and edit switch modules.""" class Meta: model = ModuleSwitch fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditModuleForm, self).__init__(*args, prefix=prefix, **kwargs) class EditSwitchModuleForm(FormRevMixin, ModelForm): """Form used to add and edit modules related to a switch.""" class Meta: model = ModuleOnSwitch fields = "__all__" def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) super(EditSwitchModuleForm, self).__init__(*args, prefix=prefix, **kwargs)