From a49e002c1399d69c5506e3360b9abab06deec965 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Tue, 19 Dec 2017 23:36:04 +0100 Subject: [PATCH] Add cnames field to interface form Allow to create/delete cnames when creating/deleting interfaces --- app/models.py | 2 +- app/network/forms.py | 7 ++++- app/network/views.py | 33 ++++++++++++++++----- app/templates/network/create_host.html | 1 + app/templates/network/create_interface.html | 1 + app/templates/network/edit_interface.html | 1 + 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/models.py b/app/models.py index 6577077..4eb7af5 100644 --- a/app/models.py +++ b/app/models.py @@ -564,7 +564,7 @@ class Mac(db.Model): class Cname(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text, nullable=False, unique=True) - interface_id = db.Column(db.Integer, db.ForeignKey('interface.id'), nullable=False, unique=True) + interface_id = db.Column(db.Integer, db.ForeignKey('interface.id'), nullable=False) def __str__(self): return str(self.name) diff --git a/app/network/forms.py b/app/network/forms.py index 7f563fe..8457381 100644 --- a/app/network/forms.py +++ b/app/network/forms.py @@ -13,7 +13,7 @@ from flask_login import current_user from wtforms import (SelectField, StringField, TextAreaField, SelectMultipleField, BooleanField, validators) from ..helpers import CSEntryForm -from ..validators import Unique, HOST_NAME_RE, VLAN_NAME_RE +from ..validators import Unique, RegexpList, HOST_NAME_RE, VLAN_NAME_RE from .. import utils, models @@ -90,6 +90,11 @@ class InterfaceForm(CSEntryForm): Unique(models.Interface)], filters=[utils.lowercase_field]) mac_id = SelectField('MAC', coerce=utils.coerce_to_str_or_none) + cnames_string = StringField( + 'Cnames', + description='space separated list of cnames (must be 2-20 characters long and contain only letters, numbers and dash)', + validators=[validators.Optional(), + RegexpList(HOST_NAME_RE)]) tags = SelectMultipleField('Tags', coerce=utils.coerce_to_str_or_none, validators=[validate_tags]) diff --git a/app/network/views.py b/app/network/views.py index 3ffb830..0caaa91 100644 --- a/app/network/views.py +++ b/app/network/views.py @@ -54,13 +54,13 @@ def create_host(): # and do the filtering here all_tags = models.Tag.query.all() tags = [tag for tag in all_tags if str(tag.id) in form.tags.data] - host.interfaces = [ - models.Interface(name=form.interface_name.data, - ip=form.ip.data, - network_id=network_id, - mac_id=form.mac_id.data, - tags=tags) - ] + interface = models.Interface(name=form.interface_name.data, + ip=form.ip.data, + network_id=network_id, + mac_id=form.mac_id.data, + tags=tags) + interface.cnames = [models.Cname(name=name) for name in form.cnames_string.data.split()] + host.interfaces = [interface] current_app.logger.debug(f'Trying to create: {host!r}') db.session.add(host) try: @@ -124,6 +124,7 @@ def create_interface(hostname): network_id=form.network_id.data, mac_id=form.mac_id.data, tags=tags) + interface.cnames = [models.Cname(name=name) for name in form.cnames_string.data.split()] current_app.logger.debug(f'Trying to create: {interface!r}') db.session.add(interface) try: @@ -142,7 +143,10 @@ def create_interface(hostname): @login_groups_accepted('admin', 'create') def edit_interface(name): interface = models.Interface.query.filter_by(name=name).first_or_404() - form = InterfaceForm(request.form, obj=interface, interface_name=interface.name) + cnames_string = ' '.join([str(cname) for cname in interface.cnames]) + form = InterfaceForm(request.form, obj=interface, + interface_name=interface.name, + cnames_string=cnames_string) ips = [interface.ip] ips.extend([str(address) for address in interface.network.available_ips()]) form.ip.choices = utils.get_choices(ips) @@ -151,6 +155,19 @@ def edit_interface(name): interface.ip = form.ip.data interface.network_id = form.network_id.data interface.mac_id = form.mac_id.data + # Delete the cnames that have been removed + new_cnames_string = form.cnames_string.data.split() + for (index, cname) in enumerate(interface.cnames): + if cname.name not in new_cnames_string: + current_app.logger.debug(f'Deleting cname: {cname}') + interface.cnames.pop(index) + db.session.delete(cname) + # Add new cnames + for name in new_cnames_string: + if name not in cnames_string: + cname = models.Cname(name=name) + current_app.logger.debug(f'Creating cname: {cname}') + interface.cnames.append(cname) all_tags = models.Tag.query.all() tags = [tag for tag in all_tags if str(tag.id) in form.tags.data] interface.tags = tags diff --git a/app/templates/network/create_host.html b/app/templates/network/create_host.html index a89e989..b2b0548 100644 --- a/app/templates/network/create_host.html +++ b/app/templates/network/create_host.html @@ -14,6 +14,7 @@ {{ render_field(form.ip) }} {{ render_field(form.interface_name, class_="text-lowercase") }} {{ render_field(form.mac_id) }} + {{ render_field(form.cnames_string) }} {{ render_field(form.tags) }} <div class="form-group row"> <div class="col-sm-10"> diff --git a/app/templates/network/create_interface.html b/app/templates/network/create_interface.html index 5fadfb9..01f4688 100644 --- a/app/templates/network/create_interface.html +++ b/app/templates/network/create_interface.html @@ -24,6 +24,7 @@ {{ render_field(form.network_id) }} {{ render_field(form.ip) }} {{ render_field(form.mac_id) }} + {{ render_field(form.cnames_string) }} {{ render_field(form.tags) }} <div class="form-group row"> <div class="col-sm-10"> diff --git a/app/templates/network/edit_interface.html b/app/templates/network/edit_interface.html index a7cfe3e..621feb7 100644 --- a/app/templates/network/edit_interface.html +++ b/app/templates/network/edit_interface.html @@ -27,6 +27,7 @@ {{ render_field(form.network_id) }} {{ render_field(form.ip) }} {{ render_field(form.mac_id) }} + {{ render_field(form.cnames_string) }} {{ render_field(form.tags) }} <div class="form-group row"> <div class="col-sm-10"> -- GitLab