From 77c0e5cc010c10faeb482de8812bf7ecc82995b1 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Wed, 23 May 2018 14:08:04 +0200
Subject: [PATCH] Use the last IP as network gateway

"gateway" tag removed. It could be re-added if needed to overwrite the
default computed gateway for example.

JIRA INFRA-339
---
 app/admin/views.py              |  6 ------
 app/defaults.py                 |  1 -
 app/models.py                   |  8 +++-----
 app/network/forms.py            | 14 +-------------
 tests/functional/test_models.py |  7 +++++++
 5 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/app/admin/views.py b/app/admin/views.py
index 69aad41..998718f 100644
--- a/app/admin/views.py
+++ b/app/admin/views.py
@@ -85,9 +85,3 @@ class NetworkAdmin(AdminModelView):
     form_overrides = {
         'vlan_name': fields.StringField,
     }
-
-    form_args = {
-        'gateway': {
-            'filters': [lambda x: x or None],
-        },
-    }
diff --git a/app/defaults.py b/app/defaults.py
index 737f7d6..4eaf8a1 100644
--- a/app/defaults.py
+++ b/app/defaults.py
@@ -28,6 +28,5 @@ defaults = [
     models.DeviceType(name='VME'),
     models.DeviceType(name='PLC'),
 
-    models.Tag(name='gateway', admin_only=True),
     models.Tag(name='IOC', admin_only=False),
 ]
diff --git a/app/models.py b/app/models.py
index dc1cf05..2dd4a6b 100644
--- a/app/models.py
+++ b/app/models.py
@@ -511,12 +511,10 @@ class Network(CreatedMixin, db.Model):
         return [addr for addr in self.ip_range()
                 if addr not in self.used_ips()]
 
+    @property
     def gateway(self):
-        """Return the network gateway"""
-        for interface in self.interfaces:
-            if 'gateway' in [tag.name for tag in interface.tags]:
-                return interface
-        return None
+        """Return the network gateway IP"""
+        return list(self.network_ip.hosts())[-1]
 
     @staticmethod
     def ip_in_network(ip, address):
diff --git a/app/network/forms.py b/app/network/forms.py
index ff5222b..37b9a7f 100644
--- a/app/network/forms.py
+++ b/app/network/forms.py
@@ -34,17 +34,6 @@ def starts_with_hostname(form, field):
         raise validators.ValidationError(f'Interface name shall start with the hostname "{hostname}"')
 
 
-def validate_tags(form, field):
-    choices = dict(field.choices)
-    for tag_id in field.data:
-        tag_name = choices.get(tag_id)
-        if tag_name == 'gateway':
-            network = models.Network.query.get(form.network_id.data)
-            existing_gateway = network.gateway()
-            if existing_gateway is not None:
-                raise validators.ValidationError(f'A gateway is already defined for network {network}: {existing_gateway}')
-
-
 def ip_in_network(form, field):
     """Check that the IP is in the network"""
     network_id_field = form['network_id']
@@ -149,8 +138,7 @@ class InterfaceForm(CSEntryForm):
         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])
+    tags = SelectMultipleField('Tags', coerce=utils.coerce_to_str_or_none)
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
diff --git a/tests/functional/test_models.py b/tests/functional/test_models.py
index fd5063d..bf2185f 100644
--- a/tests/functional/test_models.py
+++ b/tests/functional/test_models.py
@@ -94,6 +94,13 @@ def test_network_available_and_used_ips(network_factory, interface_factory):
     assert list(network2.available_ips()) == []
 
 
+def test_network_gateway(network_factory):
+    network = network_factory(address='192.168.0.0/24')
+    assert str(network.gateway) == '192.168.0.254'
+    network = network_factory(address='172.16.110.0/23')
+    assert str(network.gateway) == '172.16.111.254'
+
+
 def test_mac_address_validation(mac_factory):
     mac = mac_factory(address='F4:A7:39:15:DA:01')
     assert mac.address == 'f4:a7:39:15:da:01'
-- 
GitLab