├── .gitignore
├── LICENSE
├── README.md
├── django-router-interface.png
├── django_network
├── django_network
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── network
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20190126_1528.py
│ └── __init__.py
│ ├── models.py
│ ├── templates
│ ├── base.html
│ └── device.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── requirements.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | env
2 | __pycache__
3 | *.pyc
4 | db.sqlite3
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ahmad Rosid Komarudin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://developer.cisco.com/codeexchange/github/repo/arrosid/django-router-interface-list)
2 |
3 | # django-router-interface-list
4 | Display Cisco router interface list using [Django](https://www.djangoproject.com/). There is also a function to switch an individual interface `on` or `off`.
5 |
6 | Here is an example display of the interface list for a Cisco router.
7 |
8 |
9 |
10 | If you click the `switch` button, the status of interface will turn `on` or `off`.
11 |
12 | If you want to try this project, you can follow these instructions.
13 |
14 |
15 | Clone the repository git clone https://github.com/ArRosid/django-router-interface-list.git
16 | Create virtual environtment virtualenv -p python3 env
17 | Activate the virtual environtment source env/bin/activate
18 | Install the requirement package pip install -r requirements.txt
19 | Run the project
20 |
21 | cd django_network
22 | python manage.py migrate
23 | python manage.py createsuperuser
24 | python manage.py runserver
25 |
26 | Open browser and type localhost:8000/admin to add devices in the address bar
27 | Go to localhost:8000 to see the devices list
28 |
29 |
--------------------------------------------------------------------------------
/django-router-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ArRosid/django-router-interface-list/c60b91e81554314585544ff57a0cbf344de73e5f/django-router-interface.png
--------------------------------------------------------------------------------
/django_network/django_network/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ArRosid/django-router-interface-list/c60b91e81554314585544ff57a0cbf344de73e5f/django_network/django_network/__init__.py
--------------------------------------------------------------------------------
/django_network/django_network/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for django_network project.
3 |
4 | Generated by 'django-admin startproject' using Django 2.1.5.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.1/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/2.1/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = 'b(o4pwr_^g41i%&138a+_py6$bz4^1=c%0)x&_!aa87i3e@w$u'
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = True
27 |
28 | ALLOWED_HOSTS = []
29 |
30 |
31 | # Application definition
32 |
33 | INSTALLED_APPS = [
34 | 'django.contrib.admin',
35 | 'django.contrib.auth',
36 | 'django.contrib.contenttypes',
37 | 'django.contrib.sessions',
38 | 'django.contrib.messages',
39 | 'django.contrib.staticfiles',
40 | 'network'
41 | ]
42 |
43 | MIDDLEWARE = [
44 | 'django.middleware.security.SecurityMiddleware',
45 | 'django.contrib.sessions.middleware.SessionMiddleware',
46 | 'django.middleware.common.CommonMiddleware',
47 | 'django.middleware.csrf.CsrfViewMiddleware',
48 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
49 | 'django.contrib.messages.middleware.MessageMiddleware',
50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
51 | ]
52 |
53 | ROOT_URLCONF = 'django_network.urls'
54 |
55 | TEMPLATES = [
56 | {
57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
58 | 'DIRS': [],
59 | 'APP_DIRS': True,
60 | 'OPTIONS': {
61 | 'context_processors': [
62 | 'django.template.context_processors.debug',
63 | 'django.template.context_processors.request',
64 | 'django.contrib.auth.context_processors.auth',
65 | 'django.contrib.messages.context_processors.messages',
66 | ],
67 | },
68 | },
69 | ]
70 |
71 | WSGI_APPLICATION = 'django_network.wsgi.application'
72 |
73 |
74 | # Database
75 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases
76 |
77 | DATABASES = {
78 | 'default': {
79 | 'ENGINE': 'django.db.backends.sqlite3',
80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
81 | }
82 | }
83 |
84 |
85 | # Password validation
86 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
87 |
88 | AUTH_PASSWORD_VALIDATORS = [
89 | {
90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
91 | },
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
97 | },
98 | {
99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
100 | },
101 | ]
102 |
103 |
104 | # Internationalization
105 | # https://docs.djangoproject.com/en/2.1/topics/i18n/
106 |
107 | LANGUAGE_CODE = 'en-us'
108 |
109 | TIME_ZONE = 'UTC'
110 |
111 | USE_I18N = True
112 |
113 | USE_L10N = True
114 |
115 | USE_TZ = True
116 |
117 |
118 | # Static files (CSS, JavaScript, Images)
119 | # https://docs.djangoproject.com/en/2.1/howto/static-files/
120 |
121 | STATIC_URL = '/static/'
122 |
--------------------------------------------------------------------------------
/django_network/django_network/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import path, include
3 |
4 | urlpatterns = [
5 | path('admin/', admin.site.urls),
6 | path('', include('network.urls'))
7 | ]
8 |
--------------------------------------------------------------------------------
/django_network/django_network/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for django_network project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_network.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/django_network/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == '__main__':
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_network.settings')
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError as exc:
10 | raise ImportError(
11 | "Couldn't import Django. Are you sure it's installed and "
12 | "available on your PYTHONPATH environment variable? Did you "
13 | "forget to activate a virtual environment?"
14 | ) from exc
15 | execute_from_command_line(sys.argv)
16 |
--------------------------------------------------------------------------------
/django_network/network/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ArRosid/django-router-interface-list/c60b91e81554314585544ff57a0cbf344de73e5f/django_network/network/__init__.py
--------------------------------------------------------------------------------
/django_network/network/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from .models import Device
3 |
4 | admin.site.register(Device)
5 |
--------------------------------------------------------------------------------
/django_network/network/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class NetworkConfig(AppConfig):
5 | name = 'network'
6 |
--------------------------------------------------------------------------------
/django_network/network/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-26 14:35
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | initial = True
9 |
10 | dependencies = [
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='Device',
16 | fields=[
17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18 | ('name', models.CharField(max_length=100)),
19 | ('host', models.CharField(max_length=70)),
20 | ('username', models.CharField(max_length=100)),
21 | ('password', models.CharField(blank=True, max_length=100)),
22 | ('device_type', models.CharField(blank=True, choices=[('router', 'Router'), ('switch', 'Switch')], max_length=100)),
23 | ('device_platform', models.CharField(blank=True, choices=[('cisco_ios', 'Cisco IOS'), ('cisco_iosxe', 'Cisco IOS XE')], max_length=100)),
24 | ],
25 | ),
26 | ]
27 |
--------------------------------------------------------------------------------
/django_network/network/migrations/0002_auto_20190126_1528.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-26 15:28
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('network', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.RenameField(
14 | model_name='device',
15 | old_name='device_platform',
16 | new_name='platform',
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/django_network/network/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ArRosid/django-router-interface-list/c60b91e81554314585544ff57a0cbf344de73e5f/django_network/network/migrations/__init__.py
--------------------------------------------------------------------------------
/django_network/network/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 |
4 | NAPALM_MAPPING = {
5 | 'cisco_ios': 'ios',
6 | 'cisco_iosxe': 'ios'
7 | }
8 |
9 | class Device(models.Model):
10 | name = models.CharField(max_length=100)
11 | host = models.CharField(max_length=70)
12 | username = models.CharField(max_length=100)
13 | password = models.CharField(max_length=100, blank=True)
14 | device_type = models.CharField(max_length=100, choices=(('router', 'Router'),('switch', 'Switch')), blank=True)
15 | platform = models.CharField(max_length=100, choices=(('cisco_ios', 'Cisco IOS'),('cisco_iosxe', 'Cisco IOS XE')), blank=True)
16 |
17 | def __str__(self):
18 | return '{}. {}'.format(self.id, self.name)
19 |
20 | @property
21 | def napalm_driver(self):
22 | return NAPALM_MAPPING[self.platform]
--------------------------------------------------------------------------------
/django_network/network/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Django Network Automation
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Device
14 |
15 |
16 | ID
17 | Name
18 | IP Address
19 |
20 | {% for device in devices %}
21 |
22 | {{ device.id }}
23 | {{ device.name }}
24 | {{ device.host }}
25 |
26 | {% endfor %}
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/django_network/network/templates/device.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Django Network Automation
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
{{ device.name }} - {{ device.host }} - interface
14 |
38 |
39 |
back
40 |
41 |
42 |
--------------------------------------------------------------------------------
/django_network/network/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/django_network/network/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.urls import path
3 | from . import views
4 |
5 | urlpatterns = [
6 | path('', views.index),
7 | path('device/', views.device, name='device')
8 | ]
--------------------------------------------------------------------------------
/django_network/network/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, redirect
2 | from django.http import HttpResponse, HttpRequest
3 | from .models import Device
4 | from napalm import get_network_driver
5 | from netmiko import ConnectHandler
6 |
7 | def index(request):
8 | devices = Device.objects.all()
9 | context = {
10 | 'devices' : devices
11 | }
12 | return render(request, 'base.html', context)
13 |
14 | def device(request, device_id):
15 | device = Device.objects.get(id=device_id)
16 |
17 | if request.method == 'POST':
18 | interface_name = request.POST.get('interface_name')
19 | enable = request.POST.get('enable')
20 | print(enable)
21 | config_cmd = ['interface {}'.format(interface_name)]
22 | if enable == "True":
23 | config_cmd.append(' shutdown')
24 | else:
25 | config_cmd.append(' no shutdown')
26 |
27 | conn_params = {
28 | 'ip': device.host,
29 | 'username': device.username,
30 | 'password': device.password,
31 | 'device_type': device.platform
32 | }
33 |
34 | print(config_cmd)
35 | with ConnectHandler(**conn_params) as device_conn:
36 | device_conn.send_config_set(config_cmd)
37 |
38 | return redirect('/device/{}'.format(device.id))
39 | if request.method == 'GET':
40 |
41 | driver = get_network_driver(device.napalm_driver)
42 | with driver(device.host, device.username, device.password) as device_conn:
43 | interfaces = device_conn.get_interfaces()
44 |
45 | print(interfaces)
46 |
47 | context = {
48 | 'device': device,
49 | 'interfaces' : interfaces
50 | }
51 | return render(request, 'device.html', context)
52 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | asn1crypto==0.24.0
2 | bcrypt==3.1.6
3 | certifi==2018.11.29
4 | cffi==1.11.5
5 | chardet==3.0.4
6 | cryptography==2.5
7 | Django==2.1.5
8 | future==0.17.1
9 | idna==2.8
10 | Jinja2==2.10
11 | junos-eznc==2.2.0
12 | lxml==4.3.0
13 | MarkupSafe==1.1.0
14 | napalm==2.3.3
15 | ncclient==0.6.3
16 | netaddr==0.7.19
17 | netmiko==2.3.0
18 | paramiko==2.4.2
19 | pyasn1==0.4.5
20 | pycparser==2.19
21 | pyeapi==0.8.2
22 | pyIOSXR==0.53
23 | PyNaCl==1.3.0
24 | pynxos==0.0.3
25 | pyserial==3.4
26 | pytz==2018.9
27 | PyYAML==3.13
28 | requests==2.21.0
29 | scp==0.13.0
30 | selectors2==2.0.1
31 | six==1.12.0
32 | textfsm==0.4.1
33 | urllib3==1.24.1
--------------------------------------------------------------------------------