I have added the ability to create a base device template for Cisco IOS, Nexus and IOS-XE.
The idea of this is to create a quick way to get a basic configuration to SSH on to the device.
For switches, the options for configuration can become quite complex as you can have either a VLAN or a physical interface and then there is the trunking of that VLAN, port channels etc. If this was an organisation it would specify the standard for this type of config.
I have left the base config quite basic and using VLAN1, which is ok for me and my labs!
My aim is to make setting up a GNS3 lab quicker.
Code for the this current version2 can be found in GitHub
Below is an example of a new IOS router. The template output is pasted into the device giving SSH access and allowing the device to be added to the device inventory.
Making the Template Page
This was quite a simple process. Mostly a copy and paste from what I already had. The part that caused me the most problems was creating the config to be neatly output on the the HTML page. If I used a single string it would be one line. I have put a multi line string on and the variables using fstrings. This looks quite readable.
The string is then split on each new line and added to a list. This list is passed into the HTML template and output line by line in a readable code format.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
@devices_blueprint.route('/baseTemplate', methods = ['GET', 'POST']) def baseTemplate(): form = BaseConfigForm() if form.validate_on_submit(): session['deviceType'] = form.deviceType.data session['os'] = form.os.data session['ip'] = form.ip.data session['subnet'] = form.subnet.data session['hostname'] = form.hostname.data session['domainName'] = form.domainName.data session['mgmtInt'] = form.mgmtInt.data session['defaultRoute'] = form.defaultRoute.data session['enablePass'] = form.enablePass.data if session['os'] == 'ios' or 'iosxe': if session['deviceType'] == 'switch': config = (f"hostname {session['hostname']}\n" f"ip domain name {session['domainName']}\n" f"no ip domain-lookup\n" f"!\n" f"interface {session['mgmtInt']}\n" f"switchport\n" f"switchport mode access\n" f"!\n" f"interface Vlan1\n" f"ip address {session['ip']} {session['subnet']}\n" f"no shut\n" f"!\n" f"crypto key generate rsa general-keys modulus 1024\n" f"!\n" f"line vty 0 15\n" f"password Stefan2020\n" f"login local\n" f"privilege level 15\n" f"transport input ssh\n" f"!\n" f"aaa new-model\n" f"username admin password 0 Stefan2020\n" f"!\n" f"enable secret 0 {session['enablePass']}\n" f"ip route 0.0.0.0 0.0.0.0 {session['defaultRoute']}") if session['deviceType'] == 'router': config = (f"hostname {session['hostname']}\n" f"ip domain name {session['domainName']}\n" f"no ip domain-lookup\n" f"!\n" f"interface {session['mgmtInt']}\n" f"ip address {session['ip']} {session['subnet']}\n" f"no shut\n" f"!\n" f"crypto key generate rsa general-keys modulus 1024\n" f"!\n" f"line vty 0 15\n" f"password Stefan2020\n" f"login local\n" f"privilege level 15\n" f"transport input ssh\n" f"!\n" f"aaa new-model\n" f"username admin password 0 Stefan2020\n" f"!\n" f"enable secret 0 {session['enablePass']}\n" f"ip route 0.0.0.0 0.0.0.0 {session['defaultRoute']}") if session['os'] == 'nexus': config = (f"ip domain-name {session['domainName']}\n" f"crypto key generate rsa modulus 1024\n" f"!\n" f"interface {session['mgmtInt']}\n" f"vrf member management\n" f"ip address {session['ip']} {session['subnet']}\n" f"!\n" f"username admin password 0 Stefan2020\n" f"vrf context management\n" f"ip route 0.0.0.0 0.0.0.0 {session['defaultRoute']}\n") config = config.split("\n") config_list = [] for line in config: config_list.append(line) return render_template('baseTemplateOutput.html', config_list=config_list) else: form = BaseConfigForm() return render_template('baseTemplate.html', form=form) |
HTML Output Page
This page does show the password. Not exacly ideal, but the password must be shown in plaintext to be pasted into the device. The only way around this is to use hashed passwords. This can easily be done. But not something I have bothered with in the lab. I would jsut need to change the enable password 0 to 4,5,7,8,9 – depending on the version.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
{% extends "base.html" %} {% block content %} <div class="jumbotron"> <h1>Device Base Template Creator</h1> </div> <div class='container'> <div class="jumbotron"> <h2>Device Configuration</h2> <ul> <li>Device Type: {{ session['deviceType'] }}</li> <li>OS Type: {{ session['os'] }}</li> <li>Device IP: {{ session['ip'] }}</li> <li>Device Subnet Mask: {{ session['subnet'] }}</li> <li>Hostname: {{ session['hostname'] }}</li> <li>Domain: {{ session['domainName'] }}</li> <li>Management Interface: {{ session['mgmtInt'] }}</li> <li>Default Route: {{ session['defaultRoute'] }}</li> <li>Enable Password: {{ session['enablePass'] }}</li> </ul> </div> </div> <div class='container'> <div class="jumbotron"> <ul class="nav nav-tabs"> <li class="nav-item"> <a class="nav-link" data-toggle="tab"><h3>Base Template</h3></a> </li> </ul> <div class="tab-pane" id="rawoutput"> {% if session['os'] == 'ios' %} <h4>IOS Base Configuration</h4> {% elif session['os'] == 'nexus' %} <h4>Nexus Base Template</h4> {% elif session['os'] == 'iosxe' %} <h4>IOS-XE Base Template</h4> {% endif %} <br> <code> {% for element in config_list %} {{ element }}<br> {% endfor %} </code> </div> </div> </div> {% endblock %} |