[PYTHON] Simple network operation by linking Cisco DNA Center and Tact Switch

Introduction

This article was posted as Day 8 of Cisco Systems Japan Advent Calendar 2019 by Cisco volunteers.

--2017 edition: https://qiita.com/advent-calendar/2017/cisco --2018 Edition: https://qiita.com/advent-calendar/2018/cisco --2019 Edition: https://qiita.com/advent-calendar/2019/cisco

What do you want to do?

--Network operations that anyone can do --Cisco DNA Center's [~~ Stemmer ~~](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%86%E3%] 83% AB% E3% 82% B9% E3% 83% 9E% E3% 83% BC% E3% 82% B1% E3% 83% 86% E3% 82% A3% E3% 83% B3% E3% 82% B0) Tips demo --Balancing business and material ――Frequently cool topics ~~ Policy, AI, Assurance ~~, not sober but often asked operations -Reuse of goods bought in 2017

What is this?

--Publish Python scripts to automate routine tasks in network management using Tact Switch --The script is API of Cisco DNA Center. Access cisco.com/dnacenter/) and the network device is controlled by the controller --Port / no shut, Vlan change, config backup using Cisco DNA Center template function --PoE port no shut, illuminate the LED to make the lab gorgeous

Completion drawing

IMG_1322.JPG

Tact switch for operation

IMG_1323.JPG

Logical configuration

SS 2019-12-08 0.19.26.png

Demo and commentary

  1. Switch port shut / no shut (illumination off / on powered via PoE)
  2. Change vlan setting of switch port (99 or 1)
  3. Simultaneous backup of switch configuration to FTP server
  4. (Bonus) Message notification that we are working now

Demo video

0:16 Demo1: Interface Shut / No shut ... LED Off / On with PoE shut / no shut 0:51 Demo2: Vlan change ... Switching between Vlan99 and Vlan1 2:00 Demo3: Configuration backup ... Backup of switch configuration to FTP server 3:27 Demo4: Notification to SNS ... Post work notifications to WebEx Teams

Settings, scripts

Raspberry Pi

We have seven Python scripts on the Raspberry Pi. One (template_switch.py) is for accepting the input of each button and executing one of the six scripts. The rest of the script directs to the Cisco DNA Center API, depending on its intended use (only one is posted directly to WebEx Teams).


pi@raspberrypi:~/code $ uname -a
Linux raspberrypi 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux
pi@raspberrypi:~/code $ ls -la
36 in total
drwxr-xr-x 2 root root 4096 December 7 03:11 .
drwxr-xr-x 21 pi pi 4096 December 6 01:29 ..
-rwxr-xr-x 1 root root 845 December 6 01:30 teams.py
-rwxr-xr-x 1 root root 1285 December 5 23:08 templateConfigbackup.py
-rwxr-xr-x 1 root root 1246 December 4 04:42 templateNoShut.py
-rwxr-xr-x 1 root root 1243 December 4 04:41 templateShut.py
-rwxr-xr-x 1 root root 1369 December 6 00:45 templateVlan1.py
-rwxr-xr-x 1 root root 1370 December 6 00:46 templateVlan99.py
-rwxr-xr-x 1 root root 1894 December 6 06:22 template_switch.py

Connect six buttons (tact switch) between each of the six GPIOs (General-purpose input / output) and GND, and then connect the following Allows Input to be accepted by the code in. For the pin layout, search appropriately or follow the model number of Raspberry Pi. Reference: Raspberry Pi 2/3 B pin layout (40 pins)

IMG_1266.jpg

template_switch.py


# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import time
import sys
import os

if __name__ == "__main__":
    pin1 = 11
    pin2 = 13
    pin3 = 15
    pin4 = 29
    pin5 = 31
    pin6 = 37

    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pin1, GPIO.IN, pull_up_down = GPIO.PUD_UP)
    GPIO.setup(pin2, GPIO.IN, pull_up_down = GPIO.PUD_UP)
    GPIO.setup(pin3, GPIO.IN, pull_up_down = GPIO.PUD_UP)
    GPIO.setup(pin4, GPIO.IN, pull_up_down = GPIO.PUD_UP)
    GPIO.setup(pin5, GPIO.IN, pull_up_down = GPIO.PUD_UP)
    GPIO.setup(pin6, GPIO.IN, pull_up_down = GPIO.PUD_UP)

    print("Waiting for button...")
    print("-- 6(noshut) - 5(shut) - 4(vlan1) - 3(vlan99) - 2(backup) - 1(message) --")

    while True:
        button1 = GPIO.input(pin1)
        button2 = GPIO.input(pin2)
        button3 = GPIO.input(pin3)
        button4 = GPIO.input(pin4)
        button5 = GPIO.input(pin5)
        button6 = GPIO.input(pin6)

        cmd = ""
        if button1 == False:
            print("Bottun1 - teams.py")
            cmd = "python ./teams.py '##I'm working on it right now##'"

        elif button2 == False:
            print("Button2 - templateConfigbackup.py")
            cmd = "python ./templateConfigbackup.py"

        elif button3 == False:
            print("Button3 - templateVlan99.py")
            cmd = "python ./templateVlan99.py"

        elif button4 == False:
            print("Button4 - templateVlan1.py")
            cmd = "python ./templateVlan1.py"

        elif button5 == False:
            print("Button5 - templateShut.py")
            cmd = "python ./templateShut.py"

        elif button6 == False:
            print("Button6 - templateNoShut.py")
            cmd = "python ./templateNoShut.py"

        if cmd != "":
            ret = os.popen(cmd).readline().strip()
            print(ret)
            time.sleep(1)

        time.sleep(0.1)

    GPIO.cleanup()

Cisco DNA Center The target device (two Catalyst 9300s in this example) must be pre-registered with the Cisco DNA Center. (Procedure omitted)

  1. Template Editor Register the Cisco IOS CLI using the Template Editor feature from the Cisco DNA Center GUI. Variables that you want to complete dynamically can be treated as variables by prefixing them with a dollar mark ($), and can be completed at runtime with a script or GUI.

1. Interface shut / no shut

SS 2019-12-08 0.40.21.png

2. Change Vlan

SS 2019-12-08 0.39.59.png

3. Copy the config to the file server

SS 2019-12-08 0.41.07.png

4. Archive using the config archive function

SS 2019-12-08 0.43.10.png

* IOS-XE settings required for config archive

archive
 log config
  logging enable
  logging size 1000
  notify syslog contenttype plaintext
  hidekeys
 path ftp://<ipaddress>/ConfigBackup/Cat9300_demo1
!
ip ftp username <ftpusername>
ip ftp password <ftppassword>

Cisco DNA Center API and Python Script

From among various, we will use the API of "Deploy Template". In the script sample below, it is included in one for the sake of clarity, such as token acquisition and path generation. (Usually, I think that files should be imported separately for efficiency and maintainability.)

SS 2019-12-08 0.53.28.png

1. Switch port shut / no shut

templateNoShut.py


import requests
import json

DNAC_URL = 'https://<dnac_ip_address>/api'
DNAC_USER = '<username>'
DNAC_PASSWORD = '<password>'

def get_token(url, user, password):
    api_call = '/system/v1/auth/token'
    url += api_call
    response = requests.post(url=url, auth=(user, password), verify=False).json()
    return response["Token"]

def deploy(token):
    headers = {
        'X-Auth-Token': token,
        'content-type': 'application/json'
        }
    url = "https://<dnac_ip_address>/api/v1/template-programmer/template/deploy"
    
    payload = {
        "templateId": "<template_id>",
        "forcePushTemplate": "true",
        "targetInfo": [
            {
                #Since there is only one port to which the LED is connected, this script specifies only one switch.
                "id": "<device_ip>",
                #The parameter specification here switches between shut and no shut.
                "params": {
                    "shutnoshut": "no shut"
                },
                "type": "MANAGED_DEVICE_IP"
            }
        ],
        }

    response = requests.post(url=url, data=json.dumps(payload), headers=headers, verify=False)
    print(response)

if __name__ == '__main__':
    token = get_token(DNAC_URL, DNAC_USER, DNAC_PASSWORD)
    deploy(token)

2. Change Vlan

templateVlan99.py


import requests
import json

DNAC_URL = 'https://<dnac_ip_address>/api'
DNAC_USER = '<username>'
DNAC_PASSWORD = '<password>'
#With the setting of multiple units, in this example we are executing for two units
ips = ["<ip_address_1>", "<ip_address_2>"]

def get_token(url, user, password):
    api_call = '/system/v1/auth/token'
    url += api_call
    response = requests.post(url=url, auth=(user, password), verify=False).json()
    return response["Token"]

def deploy(token, ipaddr):
    headers = {
        'X-Auth-Token': token,
        'content-type': 'application/json'
        }
    url = "https://<dnac_ip_address>/api/v1/template-programmer/template/deploy"
    
    payload = {
        "templateId": "<template_id>",
        "forcePushTemplate": "true",
        "targetInfo": [
            {
                "id": ipaddr, 
                #If there are multiple variables in the Template, specify them here as well.
                #The value of Vlan and the interface name are specified.
                "params": {
                    "vlan": "99",
                    "interface": "range GigabitEthernet 1/0/6-10"
                },
                "type": "MANAGED_DEVICE_IP"
            }
        ],
        }

    response = requests.post(url=url, data=json.dumps(payload), headers=headers, verify=False)
    print(response)

if __name__ == '__main__':
    token = get_token(DNAC_URL, DNAC_USER, DNAC_PASSWORD)
    for ip in ips:  
        deploy(token, ip)

3. Copy IOS config to file server

templateConfigbackup.py


import requests
import json

DNAC_URL = 'https://<dnac_ip_address>/api'
DNAC_USER = '<username>'
DNAC_PASSWORD = '<password>'
#With the setting of multiple units, in this example we are executing for two units
ips = ["<ip_address_1>", "<ip_address_2>"]

def get_token(url, user, password):
    api_call = '/system/v1/auth/token'
    url += api_call
    response = requests.post(url=url, auth=(user, password), verify=False).json()
    return response["Token"]

def deploy(token, ipaddr):
    headers = {
        'X-Auth-Token': token,
        'content-type': 'application/json'
        }
    url = "https://10.71.130.53/api/v1/template-programmer/template/deploy"
    
    payload = {
        #This is the simplest pattern in the template that does not handle variables.
        #We are demonstrating two types of config backup methods.
        #"templateId": "<template_id_1>",
        "templateId": "<template_id_2>",
        "forcePushTemplate": "true",
        "targetInfo": [
            {
                "id": ipaddr,
                "type": "MANAGED_DEVICE_IP"
            }
        ],
        }

    response = requests.post(url=url, data=json.dumps(payload), headers=headers, verify=False)
    print(response)

if __name__ == '__main__':
    token = get_token(DNAC_URL, DNAC_USER, DNAC_PASSWORD)
    for ip in ips: 
        deploy(token, ip)

4. Message notification to WebEx Team

I'm exhausted, so I just send a fixed message. At the push of a button, someone will make a lot of communication checks, document the results and post them ...

teams.py


# -*- coding: utf-8 -*-
import requests
import sys

ACCESS_TOKEN = "<access_token>"
ROOM_ID = "<room_id>"
YOUR_MESSAGE = sys.argv[1]

#Header creation
def setHeaders():
    accessToken_hdr = 'Bearer ' + ACCESS_TOKEN
    spark_header = {'Authorization': accessToken_hdr, 'Content-Type': 'application/json; charset=utf-8'}
    return spark_header

#Post a message in space
def postMsg(the_header,roomId,message):
    message = '{"roomId":"' + roomId + '","text":"' + message +'"}'
    uri = 'https://api.ciscospark.com/v1/messages'
    resp = requests.post(uri, data=message, headers=the_header)
    print resp

header=setHeaders()
postMsg(header,ROOM_ID,YOUR_MESSAGE)

Summary

Operation that anyone can do

Ultimate simplicity. How about a common task with the touch of a button?

Suitable / unsuitable for using the controller

If you access the device directly from the tact switch, for example by linking to Ansible or using Netconf / Restconf, you do not need something like Cisco DNA Center. If you have a small number of devices, or if the template content is heavily customized for local operations, you may not want a controller.

On the other hand, people who are not in charge of networks in the first place, such as having a large number of switches (hundreds), not wanting to absorb the difference in operation of each device with a script, or not wanting to ensure scalability or availability with a script execution server. If you want to link network operations with applications, or in such cases, it is better to have a controller.

For a wide range of leveled areas (entire LAN, entire DC, etc.) via the controller, and for areas with many local and custom operations (such as HQ WAN connection), directly without using the controller. It is good to use it properly. You will be freed from the hassle of thinking about maintenance and operation of the playbook.

Simple and generalized script

Did you know through the sample script that the handling of network devices is hidden? It was confirmed that what was said on page 15 of the following slide was realized to some extent even with very familiar operations (shut / no shut, vlan change, etc.).

[Interop Tokyo 2016] Introduction of SDN controller APIC-EM for LAN / WAN

Of course, the functionality itself has evolved to be more intent-based, and in terms of Cisco DNA Center, APIs such as Assurance, SD-Access, and Application Policy will give you a sense of the future.

Template Editor for Cisco DNA Center

Cisco DNA Center is a network management platform that is positioned as an intent-based policy controller + data platform, but it can also be used as a macro controller that turns the configuration (CLI) that is used continuously like Template Editor. From a higher-level script or another application, it seems that common tasks can be automated by linking to the CLI template and hitting the API.

Software, hardware, API, network engineer

Although it is said that software can do anything, many network shops love hardware ~~. There must have been a time when everyone was excited about wiring to the rack. On the other hand, it has also become an important mission to connect the network and higher-level systems using the API of the completely open network infrastructure, and to connect automation linked with another system using the API. .. Network engineers who can connect hardware, software, and business applications should have a bright future.

So, it was a good break to play with the breadboard and jumper wire once in a while.

application

--Tact switch used for input-> Toggle switch, sensor input, etc. --Network operation-> In addition to setting changes, communication confirmation test, route switching, etc. --Notification-> In addition to email and SNS, notification with different LED lighting patterns, display on mini LCD, etc. --Other-> Take a picture of the operator with a camera and record it

There are various possibilities!

What I used

-Raspberry Pi 3B, breadboard, jumper wire (male / male, male / female), tact switch -PoE Splitter (TP-Link TL-POE10R) -LED wire light (2.1mm jack, 12V input) -Catalyst9300 24P Two

Reference URL, book

--Cisco blog to help you with template features

Disclaimer

The opinions expressed on this site and the corresponding comments are the personal opinions of the contributor and not the opinions of Cisco. The content of this site is provided for informational purposes only and is not intended to be endorsed or expressed by Cisco or any other party. By posting on this website, each user is solely responsible for the content of all information uploaded by posting, linking or other means, and disclaims Cisco from any responsibility regarding the use of this website. I agree.

Recommended Posts

Simple network operation by linking Cisco DNA Center and Tact Switch
I made a simple network camera by combining ESP32-CAM and RTSP.
Simple neural network theory and implementation