diff --git a/app/models.py b/app/models.py index 6577077d113e2433bef8dae27e6f29635c967694..4eb7af5d54e60d8f4232cfbaaf1b7b86efa3ef2a 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 7f563fec9add6daacb4b5cfa49d9662a877cdf61..84573811c6fea5386f6be6ca6fb8f852f6652be8 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 3ffb830a298a32731f674a44f9cfd6979bf4c78f..0caaa91866c69182e7df93332553d0eb203cfe38 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 a89e989b9691157bec3533cd52a07201529e2c61..b2b054835d565d49612df7fe9ef522e687325567 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 5fadfb9525a6c66ee552cb52a52f8afd72c150a2..01f46882a1a4da8c98efc201f76ce8e7a203853b 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 a7cfe3e6632cfd115b23f902abd32b4c7d834de5..621feb7253cbffb924f8c4fdc295a38e0815e32e 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">