From 8d4e8f94cc14dfc96a6809985bfb16d25e705f20 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Mon, 18 Dec 2017 13:41:10 +0100
Subject: [PATCH] Pass selected values to register network form

Allow to customize the default selected values:
- the default network prefix can be defined in the configuration (default to 24)
- the default first and last IP chosen can probably be improved
  it defaults to hosts[9] and hosts[-5] if the list has more than 15
  elements or the first and last otherwise

Note that when using a small prefix (< 19), the number of possilbe IPs is quite
large and updating the first and last IP select field takes some time...
---
 app/network/views.py      | 35 ++++++++++++++++++++++++++++-------
 app/settings.py           |  2 ++
 app/static/js/networks.js | 13 +++++++------
 3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/app/network/views.py b/app/network/views.py
index 96c4711..a75380c 100644
--- a/app/network/views.py
+++ b/app/network/views.py
@@ -161,10 +161,20 @@ def retrieve_vlan_and_prefix(scope_id):
         scope = models.NetworkScope.query.get(scope_id)
     except sa.exc.DataError:
         current_app.logger.warning(f'Invalid scope_id: {scope_id}')
-        data = {'vlans': [], 'prefixes': []}
+        data = {'vlans': [], 'prefixes': [],
+                'selected_vlan': '', 'selected_prefix': ''}
     else:
-        data = {'vlans': [vlan_id for vlan_id in scope.available_vlans()],
-                'prefixes': scope.prefix_range()}
+        vlans = [vlan_id for vlan_id in scope.available_vlans()]
+        prefixes = scope.prefix_range()
+        default_prefix = current_app.config['NETWORK_DEFAULT_PREFIX']
+        if default_prefix in prefixes:
+            selected_prefix = default_prefix
+        else:
+            selected_prefix = prefixes[0]
+        data = {'vlans': vlans,
+                'prefixes': prefixes,
+                'selected_vlan': vlans[0],
+                'selected_prefix': selected_prefix}
     return jsonify(data=data)
 
 
@@ -175,9 +185,11 @@ def retrieve_subnets(scope_id, prefix):
         scope = models.NetworkScope.query.get(scope_id)
     except sa.exc.DataError:
         current_app.logger.warning(f'Invalid scope_id: {scope_id}')
-        data = []
+        data = {'subnets': [], 'selected_subnet': ''}
     else:
-        data = [subnet for subnet in scope.available_subnets(int(prefix))]
+        subnets = [subnet for subnet in scope.available_subnets(int(prefix))]
+        data = {'subnets': subnets,
+                'selected_subnet': subnets[0]}
     return jsonify(data=data)
 
 
@@ -188,7 +200,16 @@ def retrieve_ips(subnet, prefix):
         address = ipaddress.ip_network(f'{subnet}/{prefix}')
     except ValueError:
         current_app.logger.warning(f'Invalid address: {subnet}/{prefix}')
-        data = []
+        data = {'ips': [], 'first': '', 'last': ''}
     else:
-        data = [str(ip) for ip in address.hosts()]
+        hosts = [str(ip) for ip in address.hosts()]
+        if len(hosts) > 15:
+            first = hosts[9]
+            last = hosts[-5]
+        else:
+            first = hosts[0]
+            last = hosts[-1]
+        data = {'ips': hosts,
+                'selected_first': first,
+                'selected_last': last}
     return jsonify(data=data)
diff --git a/app/settings.py b/app/settings.py
index e3a6caa..27fc11d 100644
--- a/app/settings.py
+++ b/app/settings.py
@@ -50,3 +50,5 @@ CSENTRY_LDAP_GROUPS = {
     'admin': 'ICS Control System Infrastructure group',
     'create': 'ICS Employees',
 }
+
+NETWORK_DEFAULT_PREFIX = 24
diff --git a/app/static/js/networks.js b/app/static/js/networks.js
index 10a2d78..d4823f7 100644
--- a/app/static/js/networks.js
+++ b/app/static/js/networks.js
@@ -1,11 +1,12 @@
 $(document).ready(function() {
 
-  function update_selectfield(field_id, data) {
+  function update_selectfield(field_id, data, selected_value) {
     var $field = $(field_id);
     $field.empty();
     $.map(data, function(option, index) {
       $field.append($("<option></option>").attr("value", option).text(option));
     });
+    $field.val(selected_value);
   }
 
   function update_vlan_and_prefix() {
@@ -15,8 +16,8 @@ $(document).ready(function() {
     $.getJSON(
       $SCRIPT_ROOT + "/network/_retrieve_vlan_and_prefix/" + scope_id,
       function(json) {
-        update_selectfield("#vlan_id", json.data.vlans);
-        update_selectfield("#prefix", json.data.prefixes);
+        update_selectfield("#vlan_id", json.data.vlans, json.data.selected_vlan);
+        update_selectfield("#prefix", json.data.prefixes, json.data.selected_prefix);
         update_address();
       }
     );
@@ -30,7 +31,7 @@ $(document).ready(function() {
     $.getJSON(
       $SCRIPT_ROOT + "/network/_retrieve_subnets/" + scope_id + "/" + prefix,
       function(json) {
-        update_selectfield("#address", json.data);
+        update_selectfield("#address", json.data.subnets, json.data.selected_subnet);
         update_first_and_last_ip();
       }
     );
@@ -43,8 +44,8 @@ $(document).ready(function() {
     $.getJSON(
       $SCRIPT_ROOT + "/network/_retrieve_ips/" + address,
       function(json) {
-        update_selectfield("#first_ip", json.data);
-        update_selectfield("#last_ip", json.data.slice().reverse());
+        update_selectfield("#first_ip", json.data.ips, json.data.selected_first);
+        update_selectfield("#last_ip", json.data.ips.slice().reverse(), json.data.selected_last);
       }
     );
   }
-- 
GitLab