瀏覽代碼

done CRUD zones #111

Roberto Berto 5 年之前
父節點
當前提交
5ef9cf0090

+ 1 - 0
requirements.txt

@@ -3,3 +3,4 @@ Django==3.0.7
 pytz==2019.3
 pytz==2019.3
 sqlparse==0.3.1
 sqlparse==0.3.1
 requests
 requests
+python-slugify

+ 80 - 0
vycontrol/firewall/templates/firewall/zones-addrule.html

@@ -0,0 +1,80 @@
+{% extends "base.html" %}
+
+{% block header_title %}Add Firewall Ruleset to Zone{% endblock %}
+{% block section_title %}Add Firewall Ruleset to Zone{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+
+<h3>interfaces</h3>
+{{ interfaces|pprint }}
+
+<h3>interfaces_all_names</h3>
+{{ interfaces_all_names|pprint }}
+
+<h3>zones</h3>
+{{ zones|pprint }}
+
+<h4>firewalls</h4>
+{{ firewalls|pprint }}
+
+{% 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>
+
+<h3>Add zone ruleset</h3>
+<form action="{% url 'firewall:firewall-zones-addrule' %}" method="post">
+    {% csrf_token %}
+
+    <p>
+        <input type="checkbox" name="reverse" id="reverse" value="1">
+        <label for="alias">create reverse ruleset (from source to destination) </label>
+    </p>        
+
+    <p>
+        <label for="dstzone">destination zone - single choice</label><br>
+        <select name="dstzone" id="dstzone" size="5" style="width: 200px;">
+            {% for zone in zones %}
+            <option value="{{ zone }}">{{ zone }}</option>
+            {% endfor %}
+        </select>
+    </p>
+
+
+    <p>
+        <label for="srczone">from zone - single choice</label><br>
+        <select name="srczone" id="srczone" size="5" style="width: 200px;">
+            {% for zone in zones %}
+            <option value="{{ zone }}">{{ zone }}</option>
+            {% endfor %}
+        </select>
+    </p>
+
+
+    <p>
+        <label for="firewall">firewall name - single choice</label><br>
+        <select name="firewall" id="firewall" size="5" style="width: 200px;">
+            {% for firewall in firewalls %}
+            <option value="{{ firewall }}">{{ firewall }}</option>
+            {% endfor %}
+        </select>
+
+    </p>
+
+    <p>
+        <input type="submit" value="Add zone ruleset">
+    </p>
+
+{% endblock %}
+
+
+

+ 36 - 0
vycontrol/firewall/templates/firewall/zones-removerule.html

@@ -0,0 +1,36 @@
+{% extends "base.html" %}
+
+{% block header_title %}Remove Firewall Zone Rule{% endblock %}
+{% block section_title %}Remove Firewall Zone Rule{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+
+<h3>interfaces</h3>
+{{ interfaces|pprint }}
+
+<h3>interfaces_all_names</h3>
+{{ interfaces_all_names|pprint }}
+
+<h3>zoneinfo</h3>
+{{ zoneinfo|pprint }}
+
+{% 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>
+
+
+
+{% endblock %}
+
+
+

+ 37 - 4
vycontrol/firewall/templates/firewall/zones.html

@@ -7,6 +7,10 @@
 {% block debug %}
 {% block debug %}
 
 
 {{ allzones_pretty }}
 {{ allzones_pretty }}
+
+<h3>allzonesrules</h3>
+{{ allzonesrules|pprint }} 
+
 {% endblock %}
 {% endblock %}
 
 
 {% block content %}
 {% block content %}
@@ -19,7 +23,8 @@
     <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
     <a href="{% url 'firewall:firewall-portgroup-list' %}">Port Group</a>
 </p>
 </p>
 <p class="submenu2">
 <p class="submenu2">
-    <a href="{% url 'firewall:firewall-zones-add' %}">Add Zone</a>
+    <a href="{% url 'firewall:firewall-zones-add' %}">Add Zone</a> | 
+    <a href="{% url 'firewall:firewall-zones-addrule' %}">Add Ruleset</a> 
 </p>
 </p>
 
 
 
 
@@ -29,9 +34,9 @@
 
 
     <table border="1" width="100%">
     <table border="1" width="100%">
     <tr>
     <tr>
-        <th>zone</th>
-        <th>description</th>
-        <th>action</th>
+        <th width="25%">zone</th>
+        <th width="50%">description</th>
+        <th width="25%">action</th>
     </tr>
     </tr>
     </tr>    
     </tr>    
     {% for zone in allzones %}
     {% for zone in allzones %}
@@ -49,6 +54,34 @@
 {% endif %}    
 {% endif %}    
 
 
 
 
+<h3>Firewall Zones Rules</h3>
+
+{% if allzonesrules %}
+
+    <table border="1" width="100%">
+    <tr>
+        <th width="25%">zone destination</th>
+        <th width="25%">zone source</th>
+        <th width="25%">firewall</th>
+        <th width="25%">action</th>
+    </tr>
+    </tr>    
+    {% for rule in allzonesrules %}
+        <tr>
+            <td>{{ rule.dstzone }}</td>
+            <td>{{ rule.srczone }}</td>
+            <td>{{ rule.firewall }}</td>
+            <td><a href="{% url 'firewall:firewall-zones-removerule' rule.dstzone rule.srczone rule.firewall %}">remove</a></td>
+        </tr>
+    {% endfor %}
+
+    </table>
+
+{% else %}
+<p>No firewall zone rules exists.</p>
+{% endif %}    
+
+
 {% endblock %}
 {% endblock %}
 
 
 
 

+ 2 - 0
vycontrol/firewall/urls.py

@@ -32,6 +32,8 @@ urlpatterns = [
 
 
     path('zones', views.firewall_zones, name='firewall-zones'),
     path('zones', views.firewall_zones, name='firewall-zones'),
     path('zones/add', views.firewall_zones_add, name='firewall-zones-add'),
     path('zones/add', views.firewall_zones_add, name='firewall-zones-add'),
+    path('zones/addrule', views.firewall_zones_addrule, name='firewall-zones-addrule'),
+    path('zones/removerule/<str:dstzone>/<str:srczone>/<str:firewall>', views.firewall_zones_removerule, name='firewall-zones-removerule'),
     path('zones/edit/<str:zonename>', views.firewall_zones_edit, name='firewall-zones-edit'),
     path('zones/edit/<str:zonename>', views.firewall_zones_edit, name='firewall-zones-edit'),
     path('zones/remove/<str:zonename>', views.firewall_zones_remove, name='firewall-zones-remove'),
     path('zones/remove/<str:zonename>', views.firewall_zones_remove, name='firewall-zones-remove'),
 
 

+ 175 - 14
vycontrol/firewall/views.py

@@ -12,7 +12,7 @@ import vycontrol_vyos_api_lib as vapilib
 import vycontrol_vyos_api as vapi
 import vycontrol_vyos_api as vapi
 import vycontrol_messages as vmsg
 import vycontrol_messages as vmsg
 
 
-
+from slugify import slugify
 from performance import timer
 from performance import timer
 from perms import is_authenticated
 from perms import is_authenticated
 import perms
 import perms
@@ -33,16 +33,16 @@ def index(request):
     #interfaces = vyos.get_interfaces()
     #interfaces = vyos.get_interfaces()
     all_instances = vyos.instance_getall_by_group(request)
     all_instances = vyos.instance_getall_by_group(request)
     hostname_default = vyos.get_hostname_prefered(request)
     hostname_default = vyos.get_hostname_prefered(request)
+    msg = vmsg.msg()
 
 
 
 
-    firewall2 = vapilib.api(
+    """firewall2 = vapilib.api(
         hostname =      hostname_default,
         hostname =      hostname_default,
         api =           'get',
         api =           'get',
         op =            'showConfig',
         op =            'showConfig',
         cmd =           {"op": "showConfig", "path": ["firewall"]},
         cmd =           {"op": "showConfig", "path": ["firewall"]},
         description =   "get all firewall",
         description =   "get all firewall",
-    )
-
+    )"""
 
 
 
 
     is_superuser = perms.get_is_superuser(request.user)
     is_superuser = perms.get_is_superuser(request.user)
@@ -61,11 +61,12 @@ def index(request):
     template = loader.get_template('firewall/list.html')
     template = loader.get_template('firewall/list.html')
     context = { 
     context = { 
         #'interfaces': interfaces,
         #'interfaces': interfaces,
-        'instances': all_instances,
-        'hostname_default': hostname_default,
-        'firewall_all':  firewall_all,
-        'username': request.user,
-        'is_superuser' : is_superuser,
+        'instances':                                all_instances,
+        'hostname_default':                         hostname_default,
+        'firewall_all':                             firewall_all,
+        'username':                                 request.user,
+        'is_superuser' :                            is_superuser,
+        'msg' :                                     msg,
     }   
     }   
     return HttpResponse(template.render(context, request))
     return HttpResponse(template.render(context, request))
 
 
@@ -1572,6 +1573,7 @@ def firewall_zones(request):
     interfaces_defined_form     = []
     interfaces_defined_form     = []
     interfaces_zone             = {}
     interfaces_zone             = {}
     allzones                    = []
     allzones                    = []
+    allzonesrules               = []
 
 
     if get_firewall_zones.success:
     if get_firewall_zones.success:
         allzones = get_firewall_zones.data
         allzones = get_firewall_zones.data
@@ -1582,9 +1584,21 @@ def firewall_zones(request):
                         interfaces_defined.append(zoneinterface)
                         interfaces_defined.append(zoneinterface)
                         interfaces_defined_form.append("interface_" + zoneinterface)
                         interfaces_defined_form.append("interface_" + zoneinterface)
                         interfaces_zone[zoneinterface] = zone
                         interfaces_zone[zoneinterface] = zone
+                if 'from' in allzones['zone'][zone]:
+                    zonerule = {}
+                    zonerule['dstzone'] = zone
 
 
+                    for zonesrc in allzones['zone'][zone]['from']:
+                        zonerule['srczone'] =       zonesrc
+
+                        if 'firewall' in allzones['zone'][zone]['from'][zonesrc]:
+                            if 'name' in allzones['zone'][zone]['from'][zonesrc]['firewall']:
+                                zonerule['firewall'] =       allzones['zone'][zone]['from'][zonesrc]['firewall']['name']
+
+                    allzonesrules.append(zonerule)
+
+                    
 
 
-    
     if 'zone' in allzones:
     if 'zone' in allzones:
         allzones2 = []
         allzones2 = []
         for zone in allzones['zone']:
         for zone in allzones['zone']:
@@ -1602,6 +1616,7 @@ def firewall_zones(request):
         'is_superuser' :                            is_superuser,
         'is_superuser' :                            is_superuser,
         'allzones':                                 allzones2,
         'allzones':                                 allzones2,
         'allzones_pretty':                          pprint.pformat(allzones2, indent=4, width=120),
         'allzones_pretty':                          pprint.pformat(allzones2, indent=4, width=120),
+        'allzonesrules' :                           allzonesrules,
 
 
     }   
     }   
     return HttpResponse(template.render(context, request))
     return HttpResponse(template.render(context, request))
@@ -1878,7 +1893,7 @@ def firewall_zones_edit(request, zonename):
     if request.POST.get('description', None) != None:
     if request.POST.get('description', None) != None:
         zonedescription = request.POST.get('description')
         zonedescription = request.POST.get('description')
         zonedescription = zonedescription.strip()
         zonedescription = zonedescription.strip()
-        if zoneinfo['description'] != zonedescription:
+        if 'description' not in zoneinfo or zoneinfo['description'] != zonedescription:
             if len(zonedescription) > 0:
             if len(zonedescription) > 0:
                 v = vapi.set_firewall_zone_description(hostname_default, zonename, zonedescription)
                 v = vapi.set_firewall_zone_description(hostname_default, zonename, zonedescription)
                 if v.success:   
                 if v.success:   
@@ -1939,12 +1954,9 @@ def firewall_zones_edit(request, zonename):
         'interfaces_all_names_dict':        interfaces_all_names_dict,
         'interfaces_all_names_dict':        interfaces_all_names_dict,
         'interfaces_all_names_dict_pretty': pprint.pformat(interfaces_all_names_dict, indent=4, width=120),
         'interfaces_all_names_dict_pretty': pprint.pformat(interfaces_all_names_dict, indent=4, width=120),
         'zoneaction':                       zoneaction,
         'zoneaction':                       zoneaction,
-
     }   
     }   
     return HttpResponse(template.render(context, request))
     return HttpResponse(template.render(context, request))
 
 
-
-
 @is_authenticated
 @is_authenticated
 def firewall_zones_remove(request, zonename):
 def firewall_zones_remove(request, zonename):
     # validation
     # validation
@@ -1986,4 +1998,153 @@ def firewall_zones_remove(request, zonename):
         "zoneinfo":                     zoneinfo,
         "zoneinfo":                     zoneinfo,
         "zonename":                     zonename,
         "zonename":                     zonename,
     }   
     }   
+    return HttpResponse(template.render(context, request))
+
+@is_authenticated
+def firewall_zones_addrule(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) 
+
+    zones = []
+    if get_firewall_zones.success:
+        allzones = get_firewall_zones.data
+        if 'zone' in allzones:
+            for zone in allzones['zone']:
+                zones.append(zone)                        
+
+    firewalls = []
+    firewall_all = vyos.get_firewall_all(hostname_default)
+    if firewall_all == False:
+        return redirect('firewall:firewall-create')
+    if 'name' in firewall_all:
+        for firewall in firewall_all['name']:
+            firewalls.append(firewall)
+
+    reverse = False
+    if request.POST.get('reverse', None) == "1":
+        reverse = True
+
+    dstzone = None
+    srczone = None
+    firewallrule = None
+
+    if request.POST.get('dstzone', None) != None:
+        dstzone = request.POST.get('dstzone').strip()
+
+    if request.POST.get('srczone', None) != None:
+        srczone = request.POST.get('srczone').strip()
+
+    if request.POST.get('firewall', None) != None:
+        firewallrule = request.POST.get('firewall').strip()
+
+    if dstzone != None and srczone != None and firewallrule != None:
+        v = vapi.set_interface_firewall_zone_addrule(hostname_default, dstzone, srczone, firewallrule)
+        if v.success:   
+            msg.add_success("Zone ruleset zone {dst} from {src} firewall {firewall} added".format(
+                dst=dstzone,
+                src=srczone,
+                firewall=firewallrule
+            ))
+        else:
+            msg.add_error("Zone ruleset {dst} from {src} firewall {firewall} not added: {reason}".format(
+                dst=dstzone,
+                src=srczone,
+                firewall=firewallrule
+            ))
+
+        if reverse == True:
+            v = vapi.set_interface_firewall_zone_addrule(hostname_default, srczone, dstzone, firewallrule)
+            if v.success:   
+                msg.add_success("Zone reverse ruleset {dst} from {src} firewall {firewall} added".format(
+                    dst=srczone,
+                    src=dstzone,
+                    firewall=firewallrule
+                ))
+            else:
+                msg.add_error("Zone reverse ruleset {dst} from {src} firewall {firewall} not added: {reason}".format(  
+                    dst=srczone,
+                    src=dstzone,
+                    firewall=firewallrule
+                ))
+
+
+
+ 
+    template = loader.get_template('firewall/zones-addrule.html')
+    context = { 
+        #'interfaces': interfaces,
+        'instances':                    all_instances,
+        'hostname_default':             hostname_default,
+        'username':                     request.user,
+        'is_superuser':                 is_superuser,
+        'interfaces':                   interfaces,
+        'interfaces_all_names_pretty':  pprint.pformat(interfaces_all_names, indent=4, width=120),
+        'interfaces_all_names':         interfaces_all_names,
+        'msg' :                         msg.get_all(),
+        'zones' :                       zones,
+        'firewalls' :                   firewalls
+    }   
+    return HttpResponse(template.render(context, request))
+
+
+
+@is_authenticated
+def firewall_zones_removerule(request, dstzone, srczone, firewall):
+    # validation
+    dstzone = dstzone.strip()
+    srczone = srczone.strip()
+    firewall = firewall.strip()
+    
+    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_zonedst    = vapi.get_firewall_zone(hostname_default, dstzone)
+    zoneinfodst             = get_firewall_zonedst.data
+    get_firewall_zonesrc    = vapi.get_firewall_zone(hostname_default, srczone)
+    zoneinfosrc             = get_firewall_zonesrc.data    
+
+    if zoneinfodst == None or zoneinfosrc == None:
+        msg.add_error("Zone not exists")
+    else:
+        v = vapi.delete_interface_firewall_zone_rule(hostname_default, dstzone, srczone)
+        if v.success:   
+            msg.add_success("Zone ruleset {dst} from {src} removed".format(  
+                dst=dstzone,
+                src=srczone,
+            ))            
+        else:
+            msg.add_error("Zone ruleset {dst} from {src} not removed: {reason}".format(  
+                dst=dstzone,
+                src=srczone,
+                reason=v.reason
+            ))
+
+    template = loader.get_template('firewall/zones-removerule.html')
+    context = { 
+        #'interfaces': interfaces,
+        'instances':                    all_instances,
+        'hostname_default':             hostname_default,
+        'username':                     request.user,
+        'is_superuser':                 is_superuser,
+        'interfaces':                   interfaces,
+        'interfaces_all_names_pretty':  pprint.pformat(interfaces_all_names, indent=4, width=120),
+        'interfaces_all_names':         interfaces_all_names,
+        'msg' :                         msg.get_all(),
+    }   
     return HttpResponse(template.render(context, request))
     return HttpResponse(template.render(context, request))

+ 31 - 0
vycontrol/vycontrol_vyos_api.py

@@ -500,3 +500,34 @@ def delete_interface_firewall_ipv4(hostname, interface_type, interface_name, dir
 
 
 
 
 
 
+def set_interface_firewall_zone_addrule(hostname, dstzone, srczone, firewall):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "set",
+        cmd =       ["zone-policy", "zone", dstzone, "from", srczone, "firewall", "name", firewall],
+        description = "set_interface_firewall_zone_addrule",
+    )
+    return v  
+
+
+def delete_interface_firewall_zone_rule(hostname, dstzone, srczone):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "delete",
+        cmd =       ["zone-policy", "zone", dstzone, "from", srczone],
+        description = "delete_interface_firewall_zone_rule",
+    )
+    return v  
+
+
+def delete_interface_firewall_zone_rule_firewall(hostname, dstzone, srczone, firewall):
+    v = vapilib.api (
+        hostname=   hostname,
+        api =       "post",
+        op =        "delete",
+        cmd =       ["zone-policy", "zone", dstzone, "from", srczone, "firewall", "name", firewall],
+        description = "delete_interface_firewall_zone_rule",
+    )
+    return v