Jelajahi Sumber

CRUD new firewall zone #110

Roberto Berto 5 tahun lalu
induk
melakukan
f7437f5968

+ 2 - 1
vycontrol/firewall/templates/firewall/addressgroup-add.html

@@ -15,7 +15,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> |
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 

+ 2 - 1
vycontrol/firewall/templates/firewall/addressgroup-desc.html

@@ -23,7 +23,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a>     | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a>  | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:firewall-addressgroup-add' %}">Add network Group</a>

+ 2 - 1
vycontrol/firewall/templates/firewall/addressgroup-list.html

@@ -14,7 +14,8 @@
     <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:firewall-addressgroup-add' %}">Add Address Group</a>

+ 2 - 1
vycontrol/firewall/templates/firewall/create.html

@@ -14,7 +14,8 @@
     <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-add' %}">Address Group</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 

+ 5 - 4
vycontrol/firewall/templates/firewall/edit.html

@@ -15,7 +15,8 @@
     <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-add' %}">Address Group</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 
@@ -32,14 +33,14 @@
     <p>
         <label for="hostname">default action</label><br>
         <input type="radio" name="action" id="action" value="accept" {% if firewall.defaultaction == "accept" %}checked="checked"{% endif %}> accept
-        <input type="radio" name="action" id="action" value="drop" {% if firewall.defaultaction == "accept" %}checked="checked"{% endif %}> drop
-        <input type="radio" name="action" id="action" value="reject" {% if firewall.defaultaction == "accept" %}checked="checked"{% endif %}> reject        
+        <input type="radio" name="action" id="action" value="drop" {% if firewall.defaultaction == "drop" %}checked="checked"{% endif %}> drop
+        <input type="radio" name="action" id="action" value="reject" {% if firewall.defaultaction == "reject" %}checked="checked"{% endif %}> reject        
     </p>
 
     
     
     <input type="submit" value="Edit Firewall">
-    </form>
+</form>
 
     
 

+ 2 - 1
vycontrol/firewall/templates/firewall/editrule.html

@@ -12,7 +12,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:addrule' firewall_name %}">Add new rule</a>

+ 2 - 1
vycontrol/firewall/templates/firewall/list.html

@@ -16,7 +16,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a> 
 </p>
 <p class="submenu2"></p>
 

+ 2 - 1
vycontrol/firewall/templates/firewall/networkgroup-add.html

@@ -15,7 +15,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> |
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 

+ 2 - 1
vycontrol/firewall/templates/firewall/networkgroup-desc.html

@@ -23,7 +23,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a>     | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a>  | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:firewall-networkgroup-add' %}">Add network Group</a>

+ 2 - 1
vycontrol/firewall/templates/firewall/networkgroup-list.html

@@ -14,7 +14,8 @@
     <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:firewall-networkgroup-add' %}">Add network Group</a>

+ 2 - 1
vycontrol/firewall/templates/firewall/portgroup-add.html

@@ -18,7 +18,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> |
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 

+ 2 - 1
vycontrol/firewall/templates/firewall/portgroup-edit.html

@@ -31,7 +31,8 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> |
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2"></p>
 

+ 2 - 1
vycontrol/firewall/templates/firewall/portgroup-list.html

@@ -14,7 +14,8 @@
     <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> |
-    <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> 
+    <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:firewall-portgroup-add' %}">Add port group</a>

+ 3 - 1
vycontrol/firewall/templates/firewall/show.html

@@ -16,7 +16,9 @@
     <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
     <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
     <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
-    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> |
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
+
 </p>
 <p class="submenu2">
     <a href="{% url 'firewall:addrule' firewall_name %}">Add new rule</a>

+ 123 - 0
vycontrol/firewall/templates/firewall/zones-add.html

@@ -0,0 +1,123 @@
+{% extends "base.html" %}
+
+{% block header_title %}Firewall Zone{% endblock %}
+{% block section_title %}Firewall Zone{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+
+{{ allzones }}
+
+{{ interfaces_defined }}
+
+{{ interfaces_zone }}
+
+{{ interfaces_pretty }}
+
+{{ interfaces_all_names_pretty }}
+
+{% endblock %}
+
+{% block content %}
+
+<p class="submenu1">
+    <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
+    <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
+    <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
+    <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a> | 
+    <a href="{% url 'firewall:firewall-zones' %}">Zones</a>
+</p>
+
+
+{% if form_added == False %}
+    <h3>Create new zone</h3>
+
+    <form action="{% url 'firewall:firewall-zones-add' %}" method="post">
+        {% csrf_token %}
+    
+        <p>
+            <label for="alias">name</label><br>
+            <input type="text" name="name" id="name" value="" size="60">
+        </p>    
+
+        <p>
+            <label for="alias">description</label><br>
+            <input type="text" name="description" id="description" value="" size="60">
+        </p>    
+        
+        <p>
+            <label for="hostname">default action</label><br>
+            <input type="radio" name="action" id="action" value="drop" {% if firewall.defaultaction == "drop" %}checked="checked"{% endif %}> drop
+            <input type="radio" name="action" id="action" value="reject" {% if firewall.defaultaction == "accept" %}checked="checked"{% endif %}> reject        
+        </p>
+
+        {% comment %}
+        <h2>Local-zone</h2>
+        <p>Local zones cannot bellong to any other interface and will be applied to the router itself.<br>
+            <input type="checkbox" name="localzone" value="1" id="localzone">
+            <label for="localzone">set as local-zone</label><br>
+        </p> 
+        {% endcomment %}
+
+
+
+    
+
+
+        <div id="interfacesdiv">
+            <h2>Interfaces to apply</h2>
+                    {% for iface in interfaces_all_names %}
+                        {% if iface.type != "loopback" %}
+                            {% if iface.vif %}
+                                {% with iface_id="interface_"|add:iface.interface_name|add:"."|add:iface.vif iface_js="interface_"|add:iface.interface_name|add:"_"|add:iface.vif  %}
+                                    {% if iface_id not in interfaces_defined_form %}
+                                        <input type="checkbox" name="{{ iface_id }}" value="{{ iface_id  }}" id="{{ iface_js }}">
+                                        <label for="{{ iface_id }}">{{ iface.type }} {{ iface.interface_name }}{% if iface.vif %}.{{ iface.vif }}{% endif %}</label><br>
+                                    {% else %}
+                                        <input type="checkbox" name="{{ iface_id }}" value="{{ iface_id  }}" id="{{ iface_js }}" disabled>
+                                        <label for="{{ iface_id }}">{{ iface.type }} {{ iface.interface_name }}{% if iface.vif %}.{{ iface.vif }}{% endif %} belongs to another zone</label><br>                            
+                                    {% endif %}
+                                {% endwith %}
+                            {% else %}
+                                {% with iface_id="interface_"|add:iface.interface_name iface_js="interface_"|add:iface.interface_name %}
+                                    {% if iface_id not in interfaces_defined_form %}
+                                        <input type="checkbox" name="{{ iface_id }}" value="{{ iface_id  }}" id="{{ iface_js }}">
+                                        <label for="{{ iface_id }}">{{ iface.type }} {{ iface.interface_name }}{% if iface.vif %}.{{ iface.vif }}{% endif %}</label><br>
+                                    {% else %}
+                                        <input type="checkbox" name="{{ iface_id }}" value="{{ iface_id  }}" id="{{ iface_js }}" disabled>
+                                        <label for="{{ iface_id }}">{{ iface.type }} {{ iface.interface_name }}{% if iface.vif %}.{{ iface.vif }}{% endif %} belongs to another zone</label><br>
+                                    {% endif %}
+                                {% endwith %}                    
+                            {% endif %}
+                        {% endif %}
+                    {% endfor %}
+        </div>    
+        
+
+        
+        <input type="submit" value="Add Firewall">
+    </form>
+
+
+    
+    <script>
+        $(document).ready(function () {                            
+            $("#localzone").change(function () {
+                if ($("#localzone").is(":checked")) {
+                    $('#interfacesdiv').hide();
+                }
+                else if ($("#localzone").not(":checked")) {
+                    $('#interfacesdiv').show();
+                }
+            });
+        });
+
+    </script>
+{% endif %}
+
+
+{% endblock %}
+
+
+

+ 99 - 0
vycontrol/firewall/templates/firewall/zones-edit.html

@@ -0,0 +1,99 @@
+{% extends "base.html" %}
+
+{% block header_title %}Firewall Zone{% endblock %}
+{% block section_title %}Firewall Zone{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+
+{{ allzones }}
+
+{{ interfaces_defined }}
+
+{{ interfaces_zone }}
+
+
+{% endblock %}
+
+{% block content %}
+
+<p class="submenu1">
+    <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
+    <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
+    <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
+    <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+</p>
+
+
+
+<h3>Create new zone</h3>
+
+<form action="{% url 'firewall:firewall-zones-add' %}" method="post">
+    {% csrf_token %}
+  
+    <p>
+        <label for="alias">name</label><br>
+        <input type="text" name="name" id="name" value="" size="60">
+    </p>    
+
+    <p>
+        <label for="alias">description</label><br>
+        <input type="text" name="description" id="description" value="" size="60">
+    </p>    
+    
+    <p>
+        <label for="hostname">default action</label><br>
+        <input type="radio" name="action" id="action" value="drop" {% if firewall.defaultaction == "drop" %}checked="checked"{% endif %}> drop
+        <input type="radio" name="action" id="action" value="reject" {% if firewall.defaultaction == "accept" %}checked="checked"{% endif %}> reject        
+    </p>
+
+    <h2>Local-zone</h2>
+    <p>Local zones cannot bellong to any other interface and will be applied to the router itself.<br>
+        <input type="checkbox" name="localzone" value="1" id="localzone">
+        <label for="localzone">set as local-zone</label><br>
+    </p> 
+
+    <div id="interfacesdiv">
+    <h2>Interfaces to apply</h2>
+    {% for key, value in interfaces.items %}
+        {% if key != "loopback" %}
+            {% for ifkey, ifvalue in value.items %}
+                {% if ifkey not in interfaces_defined %}
+                    <input type="checkbox" name="interface_{{ ifkey }}" value="{{ ifkey }}" id="interface_{{ ifkey }}">
+                    <label for="interface_{{ ifkey }}">{{ key }} - {{ ifkey }}</label><br>
+                {% else %}
+                {{ key }} - {{ ifkey }} - already defined in zone {{ interfaces_zone|get_item:ifkey }} <br>
+
+                {% endif %}
+            {% endfor %}
+        {% endif %}
+    {% endfor %}
+    </div>
+
+    
+    <input type="submit" value="Add Firewall">
+</form>
+
+
+   
+<script>
+    $(document).ready(function () {                            
+        $("#localzone").change(function () {
+            if ($("#localzone").is(":checked")) {
+                $('#interfacesdiv').hide();
+            }
+            else if ($("#localzone").not(":checked")) {
+                $('#interfacesdiv').show();
+            }
+        });
+    });
+
+</script>
+
+
+
+{% endblock %}
+
+
+

+ 35 - 0
vycontrol/firewall/templates/firewall/zones.html

@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+
+{% block header_title %}Firewall Zones{% endblock %}
+{% block section_title %}Firewall Zones{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+
+{{ allzones_pretty }}
+{% endblock %}
+
+{% block content %}
+
+<p class="submenu1">
+    <a href="{% url 'firewall:firewall-list' %}">Firewall List</a> | 
+    <a href="{% url 'firewall:firewall-create' %}">Create new firewall</a> | 
+    <a href="{% url 'firewall:firewall-addressgroup-list' %}">Address Group</a> | 
+    <a href="{% url 'firewall:firewall-networkgroup-list' %}">Network Group</a> | 
+    <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
+</p>
+<p class="submenu2">
+    <a href="{% url 'firewall:firewall-zones-add' %}">Add Zone</a>
+</p>
+
+
+<h3>Firewall Zones</h3>
+
+<p>No firewall zone exists.</p>
+    
+
+
+{% endblock %}
+
+
+

+ 2 - 0
vycontrol/firewall/urls.py

@@ -30,6 +30,8 @@ urlpatterns = [
     path('firewall-portgroup-del/<str:groupname>', views.firewall_portgroup_del, name='firewall-portgroup-del'),
     path('firewall-portgroup-edit/<str:groupname>', views.firewall_portgroup_edit, name='firewall-portgroup-edit'),
 
+    path('zones', views.firewall_zones, name='firewall-zones'),
+    path('zones/add', views.firewall_zones_add, name='firewall-zones-add'),
 
 
     path('addrule/<str:firewall_name>', views.addrule, name='addrule'),

+ 167 - 12
vycontrol/firewall/views.py

@@ -28,7 +28,6 @@ from filters.vycontrol_filters import get_item_network
 
 
 
-
 @is_authenticated
 def index(request):
     #interfaces = vyos.get_interfaces()
@@ -118,8 +117,7 @@ def firewall_removerule(request, firewall_name, firewall_rulenumber):
 
     return redirect('firewall:show', firewall_name)
 
-
-def changerule(request, firewall_name, mode, template_name="firewall/addrule.html", rulenumber = None):
+def changerule(request, firewall_name, mode, rulenumber=None):
     msg = vmsg.msg()
 
     #interfaces = vyos.get_interfaces()
@@ -132,11 +130,14 @@ def changerule(request, firewall_name, mode, template_name="firewall/addrule.htm
     changed = False
     rulenumber_valid = False
     ruledata = {}
-            
+
+    # netservices /etc/services parser
+    netservices = network.get_services()
+
+    # firewall groups         
     firewall_group['network-group'] = {}
     firewall_group['address-group'] = {}
     firewall_group['port-group'] = {}
-
     firewall_group_raw = vapi.get_firewall_group(hostname_default)
     if firewall_group_raw.success:
         if 'network-group' in firewall_group_raw.data:
@@ -148,8 +149,6 @@ def changerule(request, firewall_name, mode, template_name="firewall/addrule.htm
         if 'port-group' in firewall_group_raw.data:
             firewall_group['port-group'] = firewall_group_raw.data['port-group']
     
-    netservices = network.get_services()
-
     # edit rule without valid rulenumber
     if mode == "editrule":
         if rulenumber == None:
@@ -179,7 +178,6 @@ def changerule(request, firewall_name, mode, template_name="firewall/addrule.htm
                 rulenumber_valid = False
                 msg.add_error("Rule number must be between 1 and 9999")
 
-
     ###############################################################################################################################################################
     # update rule action
     if rulenumber_valid and request.POST.get('ruleaction', None) != None:
@@ -941,7 +939,7 @@ def changerule(request, firewall_name, mode, template_name="firewall/addrule.htm
     ruledata_json = json.dumps(ruledata)
     #vmsg.log("json", ruledata_json)
 
-    template = loader.get_template(template_name)
+    template = loader.get_template("firewall/editrule.html")
     context = { 
         #'interfaces': interfaces,
         'instances':                        all_instances,
@@ -966,11 +964,11 @@ def changerule(request, firewall_name, mode, template_name="firewall/addrule.htm
     
 @is_authenticated
 def addrule(request, firewall_name):
-    return changerule(request, firewall_name, mode="addrule", template_name="firewall/editrule.html", rulenumber = None)
+    return changerule(request, firewall_name, mode="addrule", rulenumber=None)
 
 @is_authenticated
 def editrule(request, firewall_name, rulenumber):
-    return changerule(request, firewall_name, mode="editrule", template_name="firewall/editrule.html", rulenumber=rulenumber)
+    return changerule(request, firewall_name, mode="editrule", rulenumber=rulenumber)
 
 @is_authenticated
 def show(request, firewall_name):
@@ -1558,4 +1556,161 @@ def firewall_edit(request, firewall_name):
         'username': request.user,
         'is_superuser' : is_superuser,
     }   
-    return HttpResponse(template.render(context, request))
+    return HttpResponse(template.render(context, request))
+
+@is_authenticated
+def firewall_zones(request):
+    # basic methods all views should call
+    all_instances = vyos.instance_getall()
+    hostname_default = vyos.get_hostname_prefered(request)
+    is_superuser = perms.get_is_superuser(request.user)
+
+    # local methods to prepare env
+    get_firewall_zones      = vapi.get_firewall_zones(hostname_default) # get all zones since we cannot allow an interface belongs more than one zone
+
+    interfaces_defined          = []
+    interfaces_defined_form     = []
+    interfaces_zone             = {}
+    allzones                    = []
+
+    if get_firewall_zones.success:
+        allzones = get_firewall_zones.data
+        if 'zone' in allzones:
+            for zone in allzones['zone']:
+                if 'interface' in allzones['zone'][zone]:
+                    for zoneinterface in allzones['zone'][zone]['interface']:
+                        interfaces_defined.append(zoneinterface)
+                        interfaces_defined_form.append("interface_" + zoneinterface)
+                        interfaces_zone[zoneinterface] = zone
+
+
+
+    template = loader.get_template('firewall/zones.html')
+    context = { 
+        #'interfaces': interfaces,
+        'instances':                                all_instances,
+        'hostname_default':                         hostname_default,
+        'username':                                 request.user,
+        'is_superuser' :                            is_superuser,
+        'allzones':                                 allzones,
+        'allzones_pretty':                          pprint.pformat(allzones, indent=4, width=120),
+
+    }   
+    return HttpResponse(template.render(context, request))
+
+
+
+@is_authenticated
+def firewall_zones_add(request):
+    msg = vmsg.msg()
+
+    # basic methods all views should call
+    all_instances       = vyos.instance_getall()
+    hostname_default    = vyos.get_hostname_prefered(request)
+    is_superuser        = perms.get_is_superuser(request.user)
+
+    # local methods to prepare env
+    interfaces              = vyos.get_interfaces(hostname_default)
+    interfaces_all_names    = vyos.get_interfaces_all_names(hostname_default)
+    get_firewall_zones      = vapi.get_firewall_zones(hostname_default) # get all zones since we cannot allow an interface belongs more than one zone
+
+    interfaces_defined          = []
+    interfaces_defined_form     = []
+    interfaces_zone             = {}
+    allzones                    = []
+
+    if get_firewall_zones.success:
+        allzones = get_firewall_zones.data
+        if 'zone' in allzones:
+            for zone in allzones['zone']:
+                if 'interface' in allzones['zone'][zone]:
+                    for zoneinterface in allzones['zone'][zone]['interface']:
+                        interfaces_defined.append(zoneinterface)
+                        interfaces_defined_form.append("interface_" + zoneinterface)
+                        interfaces_zone[zoneinterface] = zone
+
+    # local control vars
+    valid               = False
+    localzone           = False
+
+    if request.POST.get('name', None) != None:
+        zonename = request.POST.get('name')
+        zonename = zonename.strip()
+
+        if request.POST.get('localzone', None) != None:
+            # set local-zone
+            v = vapi.set_firewall_zone_localzone(hostname_default, zonename)
+            if v.success:   
+                valid = True
+                msg.add_success("Local-zone defined")       
+            else:
+                msg.add_success("Local-zone failed to set") 
+        else:
+            # add all interfaces
+            interfaces_form = []
+            for rv in request.POST:
+                iface_form = None
+                if rv.startswith("interface_"):
+                    rvprefixlen = len("interface_")
+                    iface_form = rv[rvprefixlen:]
+                    interfaces_form.append(iface_form)
+
+                    v = vapi.set_firewall_zone_interface(hostname_default, zonename, iface_form)
+                    if v.success:   
+                        valid = True
+                        msg.add_success("Interface added to zone: " +  iface_form)
+                    else:
+                        msg.add_success("Interface not added to zone: " +  iface_form + " - "  + v.reason)
+
+            if valid == True:
+                # if editing remove localzone if set
+                pass
+
+
+        if valid == True:
+            if request.POST.get('description', None) != None:
+                zonedescription = request.POST.get('description')
+                zonedescription = zonedescription.strip()
+                if len(zonedescription) > 0:
+                    v = vapi.set_firewall_zone_description(hostname_default, zonename, zonedescription)
+                    if v.success:   
+                        valid = True
+                        msg.add_success("Description defined")
+                    else:
+                        msg.add_success("Description failed to set")
+
+            if request.POST.get('action', None) != None:
+                zoneaction = request.POST.get('action')
+                zoneaction = zonedescription.strip()
+                if zoneaction in ['drop', 'reject']:
+                    v = vapi.set_firewall_zone_defaultaction(hostname_default, zonename, zoneaction)
+                    if v.success:   
+                        valid = True
+                        msg.add_success("Default action defined")       
+                    else:
+                        msg.add_success("Default action failed to set")                        
+
+
+            msg.add_success("Zone added") 
+
+    template = loader.get_template('firewall/zones-add.html')
+    context = { 
+        #'interfaces': interfaces,
+        'instances':                    all_instances,
+        'hostname_default':             hostname_default,
+        'username':                     request.user,
+        'is_superuser':                 is_superuser,
+        'interfaces':                   interfaces,
+        'interfaces_pretty':            pprint.pformat(interfaces, indent=4, width=120),
+        'interfaces_all_names_pretty':  pprint.pformat(interfaces_all_names, indent=4, width=120),
+        'interfaces_all_names':         interfaces_all_names,
+        'msg' :                         msg.get_all(),
+        'allzones':                     allzones,
+        'interfaces_defined':           interfaces_defined,
+        'interfaces_defined_form':      interfaces_defined_form,
+        'interfaces_zone':              interfaces_zone,
+        'form_added':                   valid,
+    }   
+    return HttpResponse(template.render(context, request))
+
+

+ 54 - 1
vycontrol/vycontrol_vyos_api.py

@@ -371,4 +371,57 @@ def set_route_static(hostname, subnet, nexthop):
         cmd =       ["protocols", "static", "route", subnet, "next-hop", nexthop],
         description = "set_route_static",
     )
-    return v
+    return v
+
+
+def set_firewall_zone_localzone(hostname, zonename):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "set",
+        cmd =       ["zone-policy", "zone", zonename, "local-zone"],
+        description = "set_firewall_zone_localzone",
+    )
+    return v    
+
+
+def set_firewall_zone_description(hostname, zonename, description):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "set",
+        cmd =       ["zone-policy", "zone", zonename, "description", description],
+        description = "set_firewall_zone_description",
+    )
+    return v    
+
+def set_firewall_zone_defaultaction(hostname, zonename, defaultaction):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "set",
+        cmd =       ["zone-policy", "zone", zonename, "default-action", defaultaction],
+        description = "set_firewall_zone_defaultaction",
+    )
+    return v  
+
+def set_firewall_zone_interface(hostname, zonename, interface):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "set",
+        cmd =       ["zone-policy", "zone", zonename, "interface", interface],
+        description = "set_firewall_zone_interface",
+    )
+    return v    
+
+def get_firewall_zones(hostname):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "get",
+        op =        "showConfig",
+        cmd =       ["zone-policy"],
+        description = "get_firewall_zones",
+    )
+    return v
+

+ 6 - 1
vycontrol/vycontrol_vyos_api_lib.py

@@ -135,9 +135,14 @@ def api(hostname, api, op, cmd, description = ""):
     try:
         resp = requests.post(api_data['api_url'], verify=False, data=post, timeout=10)
     except requests.exceptions.ConnectionError:
+        try:
+            status_code = resp.status_code
+        except UnboundLocalError:
+            status_code = 0
+        
         v = vyapi(result = False, reason= {
             'exception'     : 'requests.exceptions.ConnectionError',
-            'respcode'      : resp.status_code
+            'respcode'      : status_code
         })
         log("failed to post url", api_data['api_url'])
 

+ 24 - 0
vycontrol/vyos.py

@@ -13,6 +13,7 @@ import perms
 def instance_getall(*args, **kwargs):
     return perms.instance_getall(*args, **kwargs)
 
+
 def get_hostname_prefered(*args, **kwargs):
     return perms.get_hostname_prefered(*args, **kwargs)
 
@@ -167,6 +168,29 @@ def get_interfaces(hostname):
     result1 = api_get(hostname, cmd)
     return result1
 
+def get_interfaces_all_names(hostname):
+    interfaces = get_interfaces(hostname)
+
+    all_names = []
+
+    for itype in interfaces:
+        for iname in interfaces[itype]:
+            all_names.append({
+                'interface_name':           iname,
+                'type':                     itype              
+            })
+            if 'vif' in interfaces[itype][iname]:
+                for vif in interfaces[itype][iname]['vif']:
+
+                    all_names.append({
+                        'interface_name':   iname,
+                        'type':             itype,
+                        'vif':              vif
+                    })                    
+    
+    return all_names
+
+
 def get_interface(interface_type, interface_name, hostname):
     cmd = {"op": "showConfig", "path": ["interfaces", interface_type, interface_name]}