From a3c407f42efe5fd9e05b1c51c547cf28e9c04d7c Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Fri, 12 Jan 2018 11:45:16 +0100
Subject: [PATCH] Fix inconsistency in interface creation

The string representation of a Network is the vlan_name.
This is what we should allow to pass as string to create an interface.

Note that if we pass network_id instead of network when creating
and interface, the validate_interfaces method from the Network class
is not called.
---
 app/api/network.py           | 3 +++
 app/models.py                | 4 ++--
 tests/functional/test_api.py | 8 ++++----
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/app/api/network.py b/app/api/network.py
index 0a0b7bf..10902ad 100644
--- a/app/api/network.py
+++ b/app/api/network.py
@@ -62,6 +62,9 @@ def get_interfaces():
 @jwt_groups_accepted('admin', 'create')
 def create_interface():
     """Create a new interface"""
+    # The validate_interfaces method from the Network class is called when
+    # setting interface.network. This is why we don't pass network_id here
+    # but network (as vlan_name string)
     return create_generic_model(models.Interface, mandatory_fields=('network', 'ip', 'name'))
 
 
diff --git a/app/models.py b/app/models.py
index fa52ac2..c6f16ba 100644
--- a/app/models.py
+++ b/app/models.py
@@ -554,9 +554,9 @@ class Interface(CreatedMixin, db.Model):
 
     def __init__(self, **kwargs):
         # Automatically convert network to an instance of Network if it was passed
-        # as an address string
+        # as a string
         if 'network' in kwargs:
-            kwargs['network'] = utils.convert_to_model(kwargs['network'], Network, 'address')
+            kwargs['network'] = utils.convert_to_model(kwargs['network'], Network, 'vlan_name')
         # WARNING! Setting self.network will call validates_interfaces in the Network class
         # For the validation to work, self.ip must be set before!
         # Ensure that ip is passed before network
diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py
index 708fc7b..889a113 100644
--- a/tests/functional/test_api.py
+++ b/tests/functional/test_api.py
@@ -606,7 +606,7 @@ def test_create_interface(client, network_factory, user_token):
     response = post(client, f'{API_URL}/network/interfaces', data={'network': network.address}, token=user_token)
     check_response_message(response, "Missing mandatory field 'ip'", 422)
 
-    data = {'network': network.address,
+    data = {'network': network.vlan_name,
             'ip': '192.168.1.20',
             'name': 'interface1'}
     response = post(client, f'{API_URL}/network/interfaces', data=data, token=user_token)
@@ -623,7 +623,7 @@ def test_create_interface(client, network_factory, user_token):
     check_response_message(response, '(psycopg2.IntegrityError) duplicate key value violates unique constraint', 422)
 
     # Check that all parameters can be passed
-    data2 = {'network': network.address,
+    data2 = {'network': network.vlan_name,
              'ip': '192.168.1.21',
              'name': 'myhostname'}
     response = post(client, f'{API_URL}/network/interfaces', data=data2, token=user_token)
@@ -637,7 +637,7 @@ def test_create_interface(client, network_factory, user_token):
 def test_create_interface_invalid_ip(ip, client, network_factory, user_token):
     network = network_factory(address='192.168.1.0/24', first_ip='192.168.1.10', last_ip='192.168.1.250')
     # invalid IP address
-    data = {'network': network.address,
+    data = {'network': network.vlan_name,
             'ip': ip,
             'name': 'hostname'}
     response = post(client, f'{API_URL}/network/interfaces', data=data, token=user_token)
@@ -647,7 +647,7 @@ def test_create_interface_invalid_ip(ip, client, network_factory, user_token):
 def test_create_interface_ip_not_in_network(client, network_factory, user_token):
     network = network_factory(address='192.168.1.0/24', first_ip='192.168.1.10', last_ip='192.168.1.250')
     # IP address not in range
-    data = {'network': network.address,
+    data = {'network': network.vlan_name,
             'ip': '192.168.2.4',
             'name': 'hostname'}
     response = post(client, f'{API_URL}/network/interfaces', data=data, token=user_token)
-- 
GitLab