By Sheldon L | Published at 2020-03-08 | Updated at 2020-03-08 |
# xml
!pip install xmltodict
import xmltodict
with open('example.xml')as f:
xml_example = f.read() # always return str
xml_dict = xmltodict.parse(xml_example)
back_to_xml = xmltodict.unparse(xml_dict)
# JSON
import json
with open('example.json') as f:
json_example = f.read()
json_dict = json.loads(json_example)
back_to_json = json.dumps(json_dict)
# YAML
!pip install yaml
import yaml
with open('example.yml') as f:
yaml_example = f.read()
yaml_dict = yaml.load(yaml_example)
back_to_yaml = yaml.dump(json_dict)
# CSV
import csv
with open('example.csv') as f:
csv_example = csv.reader(f)
for row in csv_example:
device = row[0],
location = row[1]
ip = row[2]
print(f'{device}, {location}, {ip}')
# YANG
import pyang # data modeling language - IETF Standard
# for NETCONF/RESTCONF/gRPC
# RESTCONF Basic request for Device Data
!pip install request
import requests, urllib3
import sys
# add parent dir to allow importing common vars,
# and suppose there's a device_info.py in parent dir
sys.path.append("..")
from device_info import ios_xel as device
# Disable self-signed Cert warning, not a nessesary
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Setup base vars for request
restconf_headers = {"Accept": "application/yang-data+json"}
restconf_base = "https://{ip}:{port}/restconf/data"
interface_url = restconf_base + "/ietf-interfaces:interfaces/interfaces={int_name}"
url = interface_url.format(
ip = device["address"],
port = device["resconf_port"],
int_name = device["GigabitEthernet2"],
)
r = requests.get(
url,
headers = restconf_headers,
auth = (device["username"], device["password"]),
verify = False
)
print(r.text)
interface = r.json()["ietf-interfaces:interface"]
print("{name}, {ip}/{mask}".format(
name = interface["name"],
ip = interface["ietf-ip:ipv4"]["address"][0]["ip"],
mask = interface["ietf-ip:ipv4"]["adress"][0]["netmask"],
))
# RESTCONF: Creating a new lookback
restconf_headers["Content-Type"] = "application/yang-data+json"
lookback = {
"name": "Lookback01",
"description": "Demo interface by RESTCONF",
"ip": "192.168.101.1",
"netmask": "255.255.255.0",
}
data = {
"ietf-interfaces:interface": {
"name": "lookback["name"],
"description": lookback["description"],
"type": "iana-if-type:softwareLookBack",
"enabled": True,
"ietf-ip:ipv4": {
"address": [
{
"ip": lookback["ip"],
"netmask": lookback["netmask"],
}
]
}
}
}
# Create url and send RESTCONF request to corel for GigE2 config
url = interface_url.format(
ip=corel_ip,
int_name=lookback["name"]
)
r = requests.put(
url,
headers = restconf_headers,
auth = (username, password),
json = data,
verify = False,
)
print("Request status code: {}".format(r.statuas_code))
# NETCONF: basic request
!pip install ncclient
import ncclient
from ncclient import manager
import xmltodict
interface_filter = """
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>{int_name}</name>
</interface>
</interfaces>
</filter>
"""
with manager.connect(
host=corel_ip,
username=username,
password=password,
hotkey_verify=False,
) as m:
# create desired NETCONF filter and <get_config>
filter = interface_filter.format(int_name = "GigabitEthernet2")
r = m.get_config("running", filter)
# process the XML to python dict
interface = xmltodict.parse(r.xml)
interface = interface["rpc-reply"]["data"]["interfaces"]["interface"]
print("{name}, {ip}/{mask}".format(
name = interface["name"]["#text"],
ip = interface["ipv4"]["address"]["ip"],
mask = interface["ipv4"]["address"]["netmask"],
))
# NETCONF: update
config_data = """<config>
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>{int_name}</name>
<description>{description}</description>
<type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">
ianaift: softwareLookack
</type>
<enabled>true</enabled>
<ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip>
<address>
<ip>{ip}</ip>
<netmask>{netmask}</netmask>
</address>
</ipv4>
</interface>
</interfaces>
</filter>
</config>"""
lookback = {
"name": "Lookback02",
"description": "Demo interface by NETCONF",
"ip": "192.168.102.1",
"netmask": "255.255.255.0",
}
with manage.connect(
host=corel_ip,
username=username,
password=password,
hotkey_verify=False,
) as m:
# create desired NETCONF config payload and <edit_config>
config = config_data.format(**lookback)
r = m.edit_config(targe="running", config=config)
print("NETCONF RPC OK: {}".format(r.ok))
# Network CLI: if no other API available ...
#
!pip install netmiko
import netmiko
# SNMP
!pip install pysnmp