From ede8c88bc4607f7d2df4e1409e8030c93a941d51 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@ess.eu> Date: Mon, 8 Jun 2020 15:53:24 +0200 Subject: [PATCH] Add description field on Interface JIRA INFRA-2112 #action In Progress --- app/models.py | 6 +++++ app/network/forms.py | 1 + app/network/views.py | 5 ++++ app/templates/network/create_interface.html | 1 + app/templates/network/edit_interface.html | 1 + app/templates/network/view_host.html | 2 ++ ...42797d9_add_interface_description_field.py | 24 +++++++++++++++++++ tests/functional/test_api.py | 2 ++ tests/functional/test_web.py | 2 +- 9 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 migrations/versions/5a2ca42797d9_add_interface_description_field.py diff --git a/app/models.py b/app/models.py index a62ed57..760c83e 100644 --- a/app/models.py +++ b/app/models.py @@ -1216,6 +1216,10 @@ class Host(CreatedMixin, SearchableMixin, db.Model): "ip": {"type": "ip"}, "netmask": {"enabled": False}, "name": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}, + "description": { + "type": "text", + "fields": {"keyword": {"type": "keyword"}}, + }, "mac": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}, "host": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}, "cnames": {"type": "text", "fields": {"keyword": {"type": "keyword"}}}, @@ -1420,6 +1424,7 @@ class Interface(CreatedMixin, db.Model): network_id = db.Column(db.Integer, db.ForeignKey("network.id"), nullable=False) ip = db.Column(postgresql.INET, nullable=False, unique=True) name = db.Column(db.Text, nullable=False, unique=True) + description = db.Column(db.Text) mac = db.Column(postgresql.MACADDR, nullable=True, unique=True) host_id = db.Column(db.Integer, db.ForeignKey("host.id"), nullable=False) @@ -1534,6 +1539,7 @@ class Interface(CreatedMixin, db.Model): "ip": self.ip, "netmask": str(self.network.netmask), "name": self.name, + "description": self.description, "mac": utils.format_field(self.mac), "host": utils.format_field(self.host), "cnames": [str(cname) for cname in self.cnames], diff --git a/app/network/forms.py b/app/network/forms.py index a5df188..528716d 100644 --- a/app/network/forms.py +++ b/app/network/forms.py @@ -209,6 +209,7 @@ class InterfaceForm(CSEntryForm): ], filters=[utils.lowercase_field], ) + interface_description = TextAreaField("Description") random_mac = BooleanField("Random MAC", default=False) mac = StringField( "MAC", diff --git a/app/network/views.py b/app/network/views.py index f1bfcd4..d8937cf 100644 --- a/app/network/views.py +++ b/app/network/views.py @@ -75,6 +75,8 @@ def create_host(): del form.host_id # First interface name shall be identical to host name del form.interface_name + # Interface description can only be added when adding or editing interface + del form.interface_description if form.validate_on_submit(): device_type_id = form.device_type_id.data network_id = form.network_id.data @@ -309,6 +311,7 @@ def create_interface(hostname): interface = models.Interface( host=host, name=form.interface_name.data, + description=form.interface_description.data, ip=form.ip.data, mac=form.mac.data, network=network, @@ -350,6 +353,7 @@ def edit_interface(name): request.form, obj=interface, interface_name=interface.name, + interface_description=interface.description, cnames_string=cnames_string, ) if not current_user.is_admin and not interface.is_main: @@ -374,6 +378,7 @@ def edit_interface(name): abort(403) try: interface.name = form.interface_name.data + interface.description = form.interface_description.data interface.ip = form.ip.data interface.mac = form.mac.data # Setting directly network_id doesn't update the relationship and bypass the checks diff --git a/app/templates/network/create_interface.html b/app/templates/network/create_interface.html index 8d8fe93..801ca67 100644 --- a/app/templates/network/create_interface.html +++ b/app/templates/network/create_interface.html @@ -21,6 +21,7 @@ {{ form.hidden_tag() }} {{ render_field(form.host_id, disabled=True) }} {{ render_field(form.interface_name, class_="text-lowercase") }} + {{ render_field(form.interface_description) }} {{ render_field(form.network_id, class_="selectize-default") }} {{ render_field(form.ip) }} {{ render_field(form.random_mac) }} diff --git a/app/templates/network/edit_interface.html b/app/templates/network/edit_interface.html index 63e81a8..66f675c 100644 --- a/app/templates/network/edit_interface.html +++ b/app/templates/network/edit_interface.html @@ -24,6 +24,7 @@ {{ form.hidden_tag() }} {{ render_field(form.host_id, disabled=True) }} {{ render_field(form.interface_name, class_="text-lowercase") }} + {{ render_field(form.interface_description) }} {{ render_field(form.network_id, class_="selectize-default") }} {{ render_field(form.ip) }} {{ render_field(form.mac) }} diff --git a/app/templates/network/view_host.html b/app/templates/network/view_host.html index d2f2712..0e86bd8 100644 --- a/app/templates/network/view_host.html +++ b/app/templates/network/view_host.html @@ -99,6 +99,7 @@ <tr> <th width="5%"></th> <th>Name</th> + <th>Description</th> <th>Cnames</th> <th>IP</th> <th>MAC</th> @@ -119,6 +120,7 @@ </form> </td> <td>{{ interface.name }}</td> + <td>{{ interface.description if interface.description }}</td> <td>{{ interface.cnames | join(' ') }}</td> <td>{{ interface.ip }}</td> <td>{{ interface.mac }}</td> diff --git a/migrations/versions/5a2ca42797d9_add_interface_description_field.py b/migrations/versions/5a2ca42797d9_add_interface_description_field.py new file mode 100644 index 0000000..43ee75c --- /dev/null +++ b/migrations/versions/5a2ca42797d9_add_interface_description_field.py @@ -0,0 +1,24 @@ +"""Add interface description field + +Revision ID: 5a2ca42797d9 +Revises: 91b0093a5e13 +Create Date: 2020-06-01 12:49:27.606851 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "5a2ca42797d9" +down_revision = "91b0093a5e13" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column("interface", sa.Column("description", sa.Text(), nullable=True)) + + +def downgrade(): + op.drop_column("interface", "description") diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py index dd5dc39..5b70c7c 100644 --- a/tests/functional/test_api.py +++ b/tests/functional/test_api.py @@ -70,6 +70,7 @@ INTERFACE_KEYS = { "ip", "netmask", "name", + "description", "mac", "domain", "host", @@ -1285,6 +1286,7 @@ def test_create_interface(client, host, network_192_168_1, no_login_check_token) "network": network_192_168_1.vlan_name, "ip": "192.168.1.21", "name": host.name + "-2", + "description": "The second interface", "host": host.name, "mac": "7c:e2:ca:64:d0:68", } diff --git a/tests/functional/test_web.py b/tests/functional/test_web.py index e9a5c6b..0771092 100644 --- a/tests/functional/test_web.py +++ b/tests/functional/test_web.py @@ -246,7 +246,7 @@ def test_retrieve_hosts(logged_client, interface_factory, host_factory): hosts = response.get_json()["data"] assert {host1.name, host2.name} == set(host["name"] for host in hosts) assert len(hosts[0]) == 15 - assert len(hosts[0]["interfaces"][0]) == 15 + assert len(hosts[0]["interfaces"][0]) == 16 def test_retrieve_hosts_by_ip(logged_client, interface_factory): -- GitLab