Эх сурвалжийг харах

edit/add/delete interfaces

Roberto Berto 4 жил өмнө
parent
commit
4591ba45f1

+ 5 - 12
README.md

@@ -1,19 +1,11 @@
-# VyControl
-
 <p align="center">
-<img align="center" width="150" height="30" src="https://storage.googleapis.com/vycontrol/logos/logotxt.png">
+<img align="center" width="150" height="30" src="https://storage.googleapis.com/vycontrol/logos/logotxt.png" alt="VyControl">
 </p>
 
 
-VyControl is a single frontend interface to manage a single or multiple VyoS servers. Only download [VyOS](https://www.vyos.io/) Rolling Release, since VyControl needs the latest VyOS API.
-
-
-Still in 2020, the most important functionalities that until then were only possible through CLI (command line interface), will be possible through a friendly web interface developed in Django / Python.
-
-Standalone VyoS installations can now have a control panel.
-
-Datacenter installations with multiple VyoS will be able to offer their customers (with users, groups and granular control) firewall as a service.
+VyControl is frontend interface to manage a single or multiple VyoS servers. 
 
+Datacenters can to offer their customers (with users, groups and granular control) firewall and router as a service.
 
 
 # Main links
@@ -29,6 +21,7 @@ Datacenter installations with multiple VyoS will be able to offer their customer
 
 # Install instructions 
 
+* download [VyOS](https://www.vyos.io/) Rolling Release, since VyControl needs the latest VyOS API.
 * for your security edit SECRET_KEY in inside Django settings/production.py and change to something random, maybe using 
 ```
 openssl rand -hex 32
@@ -88,7 +81,7 @@ http://127.0.0.1:8000/
 - [ ] Discussion VyControl at VyOS forum https://forum.vyos.io/t/vycenter-alpha-stage-announcement-vyos-web-interface/5221/4
 
 # changelog
-- [x] edit interfaces
+- [x] edit/add/delete interfaces
 - [x] lost password recovery using external SMTP server
 - [x] NTP servers add/list/delete
 - [x] zone based firewall

+ 1 - 0
requirements.txt

@@ -4,3 +4,4 @@ pytz==2021.1
 sqlparse==0.4.1
 requests
 python-slugify
+validators

+ 1 - 1
vycontrol/config/views.py

@@ -20,7 +20,7 @@ from django.template.defaultfilters import register
 from perms import is_authenticated
 import perms
 
-from filters.vycontrol_filters import get_item
+from libs.vycontrol_filters import get_item
 
 
 

+ 3 - 3
vycontrol/firewall/views.py

@@ -22,9 +22,9 @@ import pprint
 import types
 
 
-from filters.vycontrol_filters import get_item
-from filters.vycontrol_filters import get_item_port
-from filters.vycontrol_filters import get_item_network
+from libs.vycontrol_filters import get_item
+from libs.vycontrol_filters import get_item_port
+from libs.vycontrol_filters import get_item_network
 
 
 

+ 95 - 0
vycontrol/interface/templates/interface/add.html

@@ -0,0 +1,95 @@
+{% extends "base.html" %}
+
+{% block header_title %}Interface add{% endblock %}
+{% block section_title %}Interface add{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+{{ interface }}
+{{ interface_type }}
+{{ interface_name }}
+{% endblock %}
+
+
+{% block content %}
+
+{% if changed == False %}
+
+    <form action="{% url 'interface:interface-add' %}" method="post">  
+    {% csrf_token %}
+
+    <table border="0" width="100%">
+        <tr>
+            <th width="30%">type</th>
+            <td>
+                <select name="type" id="type">
+                    <option value="ethernet">ethernet</option>
+                    <option value="dummy">dummy</option>
+                    <option value="loopback">loopback</option>
+                </select>
+            </td>
+        </tr>
+
+        <tr>
+            <th width="30%">name</th>
+            <td><input type="text" name="name" id="name"></td>
+        </tr>
+        
+        <tr>
+            <th width="30%">dhcp</th>
+            <td width="70%">
+                <input type="checkbox" name="dhcp" value="1" id="dhcp">
+            </td>
+        </tr>
+        
+        
+
+        <tr id="tr_address" style="display:none">
+        <th>address</th> 
+        <td><input type="text" name="address"  id="address"></td>
+        </tr>
+
+        <tr>
+        <th>mtu</th> 
+        <td><input type="text" name="mtu"  id="mtu"></td>
+        </tr>
+
+    </table>
+
+    <input type="submit" value="Add Interface">
+
+    </form>
+
+
+
+    <script>
+        $(document).ready(function () {   
+            $("#dhcp").click(function () {
+                if ($("#dhcp").is(':checked')) {
+                    $('#tr_address').hide();
+                } else {
+                    $('#tr_address').show();
+                }
+
+            });
+
+            if ($("#dhcp").is(':checked')) {
+                $('#tr_address').hide();
+            } else {
+                $('#tr_address').show();
+            }
+
+        })
+    </script>
+
+{% else %}
+<p class="submenu1">
+    <a href="{% url 'interface:interface-list' %}">List Interfaces</a> 
+</p>
+<p class="submenu2"></p>
+{% endif %}
+
+
+{% endblock %}
+
+

+ 88 - 0
vycontrol/interface/templates/interface/add_vlan.html

@@ -0,0 +1,88 @@
+{% extends "base.html" %}
+
+{% block header_title %}Interface add vlan{% endblock %}
+{% block section_title %}Interface add vlan{% endblock %}
+{% block username %}{{ username }}{% endblock %}
+
+{% block debug %}
+{{ interface }}
+{{ interface_type }}
+{{ interface_name }}
+{% endblock %}
+
+
+{% block content %}
+
+{% if changed == False %}
+
+    <form action="{% url 'interface:interface-add-vlan' %}" method="post">  
+    <input type="hidden" name="interface_type" id="interface_type" value="{{ interface_type }}">
+    <input type="hidden" name="interface_name" id="interface_name" value="{{ interface_name }}">
+
+    {% csrf_token %}
+
+    <table border="0" width="100%">
+        
+        <tr>
+            <th width="30%">vlan</th>
+            <td><input type="text" name="vlan" id="vlan"></td>
+        </tr>
+        
+        <tr>
+            <th width="30%">dhcp</th>
+            <td width="70%">
+                <input type="checkbox" name="dhcp" value="1" id="dhcp">
+            </td>
+        </tr>
+        
+        
+
+        <tr id="tr_address" style="display:none">
+        <th>address</th> 
+        <td><input type="text" name="address"  id="address"></td>
+        </tr>
+
+        <tr>
+        <th>mtu</th> 
+        <td><input type="text" name="mtu"  id="mtu"></td>
+        </tr>
+
+    </table>
+
+    <input type="submit" value="Add Interface Vlan">
+
+    </form>
+
+
+
+    <script>
+        $(document).ready(function () {   
+            $("#dhcp").click(function () {
+                if ($("#dhcp").is(':checked')) {
+                    $('#tr_address').hide();
+                } else {
+                    $('#tr_address').show();
+                }
+
+            });
+
+            if ($("#dhcp").is(':checked')) {
+                $('#tr_address').hide();
+            } else {
+                $('#tr_address').show();
+            }
+
+        })
+    </script>
+
+{% else %}
+<p class="submenu1">
+    <a href="{% url 'interface:interface-list' %}">List Interfaces</a> 
+</p>
+<p class="submenu2"></p>
+{% endif %}
+
+
+{% endblock %}
+
+

+ 15 - 1
vycontrol/interface/templates/interface/index.html

@@ -18,12 +18,19 @@
 
 {% block content %}
 
+<p class="submenu1">
+    <a href="{% url 'interface:interface-add' %}">Create new interface</a>
+</p>
+<p class="submenu2"></p>
+
+
+
 {% if interfaces %}
     <form action="{% url 'interface:interface-list' %}" method="post">
         {% csrf_token %}
 
         <table border="1" width="100%">
-        <tr><th>type</th><th>name</th><th>address</th><th>firewall ipv4 in</th><th>firewall ipv4 out</th></th></tr>
+        <tr><th>type</th><th>name</th><th>address</th><th>firewall ipv4 in</th><th>firewall ipv4 out</th><th>actions</th></tr>
 
 
         {% for iname in interfaces_all_names %}
@@ -66,6 +73,13 @@
                     {% endif %}
                 </td>
 
+                <td>
+                    {% if iname.vif == None %}
+                        <a href="{% url 'interface:interface-delete' interface_type=iname.type interface_name=iname.interface_short %}">delete</a></td>              
+                    {% else %}
+                        <a href="{% url 'interface:interface-delete' interface_type=iname.type interface_name=iname.interface_short interface_vif=iname.vif %}">delete</a></td>              
+                    {% endif %}
+
             </tr>
         {% endfor %}
         </table>

+ 32 - 1
vycontrol/interface/templates/interface/show.html

@@ -13,6 +13,13 @@
 
 {% block content %}
 
+{% if interface_type == "ethernet" and interface_vif == None %}
+<p class="submenu1">
+    <a href="{% url 'interface:interface-add-vlan' interface_type=interface_type interface_name=interface_name %}">Create new vlan</a> 
+</p>
+<p class="submenu2"></p>
+{% endif %}
+
 
 {% if interface %}
 
@@ -77,7 +84,31 @@
         </form>
     </div>
 
-    
+    {% if interface_type == "ethernet" and interface_vif == None %}
+
+    {% if interface_children|length > 0 %}
+        <h2>Vlans</h2>
+
+        <table border="1" width="100%">
+            <th width="30%">Vlan ID</th>
+            <th width="40%">Actions</th>
+        </tr>
+
+        {% for children in interface_children %}
+        <tr>
+            <td><a href="{% url 'interface:interface-show' interface_type=interface_type interface_name=interface_name|add:"."|add:children.vif %}">{{ children.vif }}</a></td>
+            <td><a href="{% url 'interface:interface-delete' interface_type=interface_type interface_name=interface_name interface_vif=children.vif %}">delete</a></td>
+        </tr>
+        {% endfor %}
+        </table>
+    {% endif %}
+
+
+    {% endif %}
+
+
+
+
 {% else %}
     <p>Invalid interface.</p>
 {% endif %}

+ 8 - 2
vycontrol/interface/urls.py

@@ -6,9 +6,15 @@ app_name = 'interface'
 
 urlpatterns = [
     path('', views.index, name='interface-list'),
-    path('interface-show/<slug:interface_type>/<str:interface_name>', views.interfaceshow, name='interface-show'),
-    path('interface-firewall/<slug:interface_type>/<str:interface_name>', views.interfacefirewall, name='interface-firewall'),
+    path('interface-show/<slug:interface_type>/<str:interface_name>', views.interface_show, name='interface-show'),
+    path('interface-firewall/<slug:interface_type>/<str:interface_name>', views.interface_firewall, name='interface-firewall'),
     path('interface-set-firewall/<slug:interface_type>/<str:interface_name>', views.interface_set_firewall, name='interface-set-firewall'),
     path('interface-set/<slug:interface_type>/<str:interface_name>', views.interface_set, name='interface-set'),
+    path('interface-delete/<slug:interface_type>/<str:interface_name>/<str:interface_vif>', views.interface_delete, name='interface-delete'),
+    path('interface-delete/<slug:interface_type>/<str:interface_name>', views.interface_delete, name='interface-delete'),
+    path('interface-add', views.interface_add, name='interface-add'),
+    path('interface-add-vlan/<slug:interface_type>/<str:interface_name>', views.interface_add_vlan, name='interface-add-vlan'),
+    path('interface-add-vlan', views.interface_add_vlan, name='interface-add-vlan'),
+
 
 ]

+ 200 - 7
vycontrol/interface/views.py

@@ -11,7 +11,8 @@ import vyos
 from perms import is_authenticated
 import perms
 import vycontrol_vyos_api as vapi
-
+from libs.vycontrol_validators import *
+import vycontrol_messages as vmsg
 
 from config.models import Instance
 
@@ -22,6 +23,7 @@ import pprint
 def get_item(dictionary, key):
     return dictionary.get(key)
 
+
 @is_authenticated    
 def index(request):
     
@@ -209,18 +211,27 @@ def index(request):
     return HttpResponse(template.render(context, request))
 
 @is_authenticated    
-def interfaceshow(request, interface_type, interface_name):
+def interface_show(request, interface_type, interface_name):
         
     all_instances = vyos.instance_getall()
     hostname_default = vyos.get_hostname_prefered(request)
+    is_superuser = perms.get_is_superuser(request.user)
+    
     firewall_all = vyos.get_firewall_all(hostname_default)  
-
     interface = vyos.get_interface(interface_type, interface_name, hostname=hostname_default)
-    is_superuser = perms.get_is_superuser(request.user)
-  
+    interface_detail = vyos.detail_interface(interface_type, interface_name)
+    interface_vif = interface_detail['vlan_id']
+    interface_name_short = interface_detail['interface_name']
+    interface_children = vyos.get_interface_children(hostname_default, interface_name_short)
+
+
+
+
     template = loader.get_template('interface/show.html')
     context = { 
+        'interface_children': interface_children,
         'interface': interface,
+        'interface_vif' : interface_vif,
         'instances': all_instances,
         'interface_type' : interface_type,
         'interface_name' : interface_name,
@@ -233,7 +244,7 @@ def interfaceshow(request, interface_type, interface_name):
 
 
 @is_authenticated    
-def interfacefirewall(request, interface_type, interface_name):
+def interface_firewall(request, interface_type, interface_name):
         
     all_instances = vyos.instance_getall()
     is_superuser = perms.get_is_superuser(request.user)
@@ -316,7 +327,189 @@ def interface_set(request, interface_type, interface_name):
     v = vapi.delete_interface_address(hostname_default, interface_type, interface_name_short, vif=interface_vif)
     v = vapi.set_interface_address(hostname_default, interface_type, interface_name_short, address, vif=interface_vif)
 
+    return redirect('interface:interface-show', interface_type=interface_type, interface_name=interface_name)
+
+@is_authenticated    
+def interface_delete(request, interface_type, interface_name, interface_vif=None):
+    hostname_default = vyos.get_hostname_prefered(request)   
+    
+    if interface_vif == None:
+        v = vapi.delete_interface(hostname_default, interface_type, interface_name)
+    else:
+        v = vapi.delete_interface(hostname_default, interface_type, interface_name, vif=interface_vif)
+
+    return redirect('interface:interface-list')
+
+@is_authenticated    
+def interface_add(request):      
+    all_instances = vyos.instance_getall()
+    is_superuser = perms.get_is_superuser(request.user)
+    hostname_default = vyos.get_hostname_prefered(request)
+    msg = vmsg.msg()
+
+    changed = False
+
+    if request.POST.get('name', None) == None:
+        pass
+    else:
+        interface_name = None
+        if validator_letters_numbers(request.POST.get('name', '').strip()):
+            interface_name = request.POST.get('name', '').strip()
+
+        interface_address = None
+        if validator_ipv4_cidr(request.POST.get('address', '')):
+            interface_address = request.POST.get('address', '').strip()
+
+        interface_dhcp = False
+        if request.POST.get('dhcp', '0') == '1':
+            interface_dhcp = True
+            interface_address = 'dhcp'
+
+        interface_mtu = None
+        if request.POST.get('mtu','').strip().isdigit():
+            interface_mtu = request.POST.get('mtu').strip()
+            try:
+                interface_mtu = int(interface_mtu)
+            except:
+                interface_mtu = 1450
+            
+            if not validators.between(interface_mtu, min=1000, max=9000):
+                interface_mtu = 1450
+        
+        interface_type = 'ethernet'
+        interface_types = ['ethernet', 'dummy', 'loopback']
+        if request.POST.get('type','ethernet') in interface_types:
+            interface_type = request.POST.get('type','ethernet')
+
+        v = vapi.set_interface(hostname_default, interface_type, interface_name)
+
+        if v.success == False:
+            msg.add_error("Action: failed to add interface - " + v.reason)
+        else:
+            msg.add_success("Action: interface added")
+            changed = True
+
+        v = vapi.set_interface_mtu(hostname_default, interface_type, interface_name, interface_mtu)
+        if v.success == False:
+            msg.add_error("Action: failed to set MTU - " + v.reason)
+        else:
+            msg.add_success("Action: MTU set")
+
+        v = vapi.set_interface_address(hostname_default, interface_type, interface_name, interface_address)
+        if v.success == False:
+            msg.add_error("Action: failed to set address - " + v.reason)
+        else:
+            msg.add_success("Action: address set")
+        
 
 
-    return redirect('interface:interface-show', interface_type=interface_type, interface_name=interface_name)
 
+    template = loader.get_template('interface/add.html')
+    context = { 
+        'instances':            all_instances,
+        'hostname_default':     hostname_default,
+        'username':             request.user,      
+        'is_superuser':         is_superuser, 
+        'msg':                  msg.get_all(),
+        'changed':              changed,
+
+
+    }       
+
+    return HttpResponse(template.render(context, request))
+
+
+@is_authenticated    
+def interface_add_vlan(request, interface_type=None, interface_name=None):      
+    all_instances = vyos.instance_getall()
+    is_superuser = perms.get_is_superuser(request.user)
+    hostname_default = vyos.get_hostname_prefered(request)
+    msg = vmsg.msg()
+
+    changed = False
+
+    if interface_type == None and interface_name == None:
+        interface_type = request.POST.get('interface_type')
+        interface_name = request.POST.get('interface_name')
+        if validator_letters_numbers(interface_type) and validator_letters_numbers(interface_name):
+            pass
+        else:
+            return redirect('interface:interface-list')
+
+
+    interface_vlan = request.POST.get('vlan', '').strip()
+    try:
+        interface_vlan = int(interface_vlan)
+    except:
+        interface_vlan = 0
+
+    if interface_vlan == 0:
+        pass
+    elif not validators.between(interface_vlan, min=1, max=4095):
+        msg.add_error("VLAN need to be between 1 and 4095")
+    else:
+        interface_address = None
+        if validator_ipv4_cidr(request.POST.get('address', '')):
+            interface_address = request.POST.get('address', '').strip()
+
+        interface_dhcp = False
+        if request.POST.get('dhcp', '0') == '1':
+            interface_dhcp = True
+            interface_address = 'dhcp'
+
+        interface_mtu = 0
+        if request.POST.get('mtu','').strip().isdigit():
+            interface_mtu = request.POST.get('mtu').strip()
+            try:
+                interface_mtu = int(interface_mtu)
+            except:
+                interface_mtu = 1450
+            
+        if not validators.between(interface_mtu, min=1000, max=9000):
+            interface_mtu = 1450
+    
+        
+        interface_mtu = str(interface_mtu)
+        interface_vlan = str(interface_vlan)
+
+        interface_type = 'ethernet'
+
+        v = vapi.set_interface(hostname_default, interface_type, interface_name, vif=interface_vlan)
+
+        if v.success == False:
+            msg.add_error("Action: failed to add interface - " + v.reason)
+        else:
+            msg.add_success("Action: interface added")
+            changed = True
+
+        v = vapi.set_interface_mtu(hostname_default, interface_type, interface_name, interface_mtu, vif=interface_vlan)
+        if v.success == False:
+            msg.add_error("Action: failed to set MTU - " + v.reason)
+        else:
+            msg.add_success("Action: MTU set")
+
+        v = vapi.set_interface_address(hostname_default, interface_type, interface_name, interface_address, vif=interface_vlan)
+        if v.success == False:
+            msg.add_error("Action: failed to set address - " + v.reason)
+        else:
+            msg.add_success("Action: address set")
+        
+
+
+
+    template = loader.get_template('interface/add_vlan.html')
+    context = { 
+        'instances':            all_instances,
+        'hostname_default':     hostname_default,
+        'username':             request.user,      
+        'is_superuser':         is_superuser, 
+        'msg':                  msg.get_all(),
+        'changed':              changed,
+
+        'interface_name':       interface_name,
+        'interface_type':       interface_type,
+
+
+    }       
+
+    return HttpResponse(template.render(context, request))

+ 0 - 0
vycontrol/filters/__init__.py → vycontrol/libs/__init__.py


+ 0 - 0
vycontrol/filters/vycontrol_filters.py → vycontrol/libs/vycontrol_filters.py


+ 14 - 0
vycontrol/libs/vycontrol_validators.py

@@ -0,0 +1,14 @@
+import validators
+from validators.utils import *
+import re
+
+
+@validator
+def validator_letters_numbers(value):
+    if re.match("^[A-Za-z0-9]*$", value):
+        return True
+       
+@validator
+def validator_ipv4_cidr(value):
+    if re.match("^(?:\d{1,3}\.){3}\d{1,3}(?:/\d\d?)?$", value):
+        return True

+ 1 - 1
vycontrol/static/views.py

@@ -11,7 +11,7 @@ import vycontrol_vyos_api_lib as vapilib
 import vycontrol_vyos_api as vapi
 
 from perms import is_authenticated
-from filters.vycontrol_filters import routeunpack
+from libs.vycontrol_filters import routeunpack
 import perms
 
 

+ 1 - 1
vycontrol/vycontrol/settings/base.py

@@ -100,7 +100,7 @@ TEMPLATES = [
                 'django.contrib.messages.context_processors.messages',
             ],
             'libraries':{
-                'vycontrol_filters.py': 'filters.vycontrol_filters',
+                'vycontrol_filters.py': 'libs.vycontrol_filters',
             },
         }        
     },

+ 40 - 1
vycontrol/vycontrol_vyos_api.py

@@ -639,4 +639,43 @@ def delete_interface_mtu(hostname, interface_type, interface_name, vif=None):
             cmd =       ["interfaces", interface_type, interface_name, "vif", vif, "mtu"],
             description = "delete_interface_mtu",
         )
-    return v        
+    return v        
+
+
+def delete_interface(hostname, interface_type, interface_name, vif=None):
+    if vif == None:
+        v = vapilib.api (
+            hostname=   hostname,
+            api =       "post",
+            op =        "delete",
+            cmd =       ["interfaces", interface_type, interface_name],
+            description = "delete_interface",
+        )
+    else:
+        v = vapilib.api (
+            hostname=   hostname,
+            api =       "post",
+            op =        "delete",
+            cmd =       ["interfaces", interface_type, interface_name, "vif", vif],
+            description = "delete_interface",
+        )
+    return v
+    
+def set_interface(hostname, interface_type, interface_name, vif=None):
+    if vif == None:
+        v = vapilib.api (
+            hostname=   hostname,
+            api =       "post",
+            op =        "set",
+            cmd =       ["interfaces", interface_type, interface_name],
+            description = "set_interface_dhcp",
+        )
+    else:
+        v = vapilib.api (
+            hostname=   hostname,
+            api =       "post",
+            op =        "set",
+            cmd =       ["interfaces", interface_type, interface_name, "vif", vif],
+            description = "set_interface_dhcp",
+        )
+    return v   

+ 39 - 20
vycontrol/vyos.py

@@ -156,6 +156,24 @@ def get_interfaces(hostname):
     result1 = api_get(hostname, cmd)
     return result1
 
+def detail_interface(interface_type, interface_name):
+    vlan = False
+    vlan_id = None
+
+    if interface_type == "ethernet":
+        isplit = interface_name.split(".")
+        if len(isplit) == 2:
+            vlan = True
+            vlan_id = isplit[1]
+            interface_name = isplit[0]
+
+    return {
+        "interface_name":   interface_name,
+        "vlan":             vlan,
+        "vlan_id":          vlan_id,
+        "interface_type":   interface_type
+    }
+
 def get_interfaces_all_names(hostname):
     interfaces = get_interfaces(hostname)
 
@@ -163,38 +181,26 @@ def get_interfaces_all_names(hostname):
 
     for itype in interfaces:
         for iname in interfaces[itype]:
+            interface_info = detail_interface(itype, iname)
+
             all_names.append({
                 'interface_name':           iname,
-                'type':                     itype              
+                'type':                     itype,
+                'interface_short':          interface_info['interface_name']
             })
+            
             if 'vif' in interfaces[itype][iname]:
                 for vif in interfaces[itype][iname]['vif']:
 
                     all_names.append({
                         'interface_name':   iname,
                         'type':             itype,
-                        'vif':              vif
+                        'vif':              vif,
+                        'interface_short':  interface_info['interface_name']
                     })                    
     
     return all_names
 
-def detail_interface(interface_type, interface_name):
-    vlan = False
-    vlan_id = None
-
-    if interface_type == "ethernet":
-        isplit = interface_name.split(".")
-        if len(isplit) == 2:
-            vlan = True
-            vlan_id = isplit[1]
-            interface_name = isplit[0]
-
-    return {
-        "interface_name":   interface_name,
-        "vlan":             vlan,
-        "vlan_id":          vlan_id,
-        "interface_type":   interface_type
-    }
 
 def get_interface(interface_type, interface_name, hostname):
     inteface_detail = detail_interface(interface_type, interface_name)
@@ -394,4 +400,17 @@ def ip_route(hostname):
     cmd = {"op": "show", "path": ["ip","route"]}
 
     result1 = api_show(hostname, cmd)
-    return result1        
+    return result1        
+
+
+def get_interface_children(hostname, interface_name):
+    interfaces_all_names = get_interfaces_all_names(hostname)
+
+    interface_children = []
+
+    for iname in interfaces_all_names:
+        if interface_name == iname['interface_name']:
+            if 'vif' in iname:
+                interface_children.append({'name': interface_name, 'vif': iname['vif'], 'type': iname['type']})
+
+    return interface_children