├── netconf-102
├── get_interfaces.xml
├── README.md
├── templates
│ └── create_subinterface.j2
├── get_capabilities.py
├── get_config_csr1000V.py
├── get_hostname.py
├── configuration_data_randomizer.py
└── create_subinterface.py
├── netconf-103
├── get_interfaces.xml
├── enable_odm_control.xml
├── README.md
├── show_ip_int_brief.txt
├── interfaces.py
├── screen_scrape_interfaces.py
└── get_interfaces_csr1000V.py
├── netconf-101
├── README.md
├── screen_scraping.py
├── get_capabilities.py
└── sandbox-nexus9kv-config.txt
├── README.md
├── .gitignore
├── contributing.md
└── LICENSE
/netconf-102/get_interfaces.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/netconf-103/get_interfaces.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/netconf-103/enable_odm_control.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
6 |
--------------------------------------------------------------------------------
/netconf-101/README.md:
--------------------------------------------------------------------------------
1 | # Examples for NETCONF 101 learning lab
2 | This sample code is illustrate in the 101 NETCONF learning lab.
3 |
4 | You can find step-by-step tutorials that walk through this sample code on [Cisco DevNet](http://developer.cisco.com/learning).
5 |
--------------------------------------------------------------------------------
/netconf-102/README.md:
--------------------------------------------------------------------------------
1 | # Examples for NETCONF 102 learning lab
2 | This sample code is used to illustrate the NETCONF 102 concepts.
3 |
4 | You can find step-by-step tutorials that walk through this sample code on [Cisco DevNet](http://developer.cisco.com/learning).
5 |
--------------------------------------------------------------------------------
/netconf-103/README.md:
--------------------------------------------------------------------------------
1 | # Examples for NETCONF 103 learning lab
2 | This sample code is used to illustrate the NETCONF 103 concepts.
3 |
4 | You can find step-by-step tutorials that walk through this sample code on [Cisco DevNet](http://developer.cisco.com/learning).
5 |
--------------------------------------------------------------------------------
/netconf-103/show_ip_int_brief.txt:
--------------------------------------------------------------------------------
1 | Interface IP-Address OK? Method Status Protocol
2 | GigabitEthernet1 172.16.126.251 YES manual up up
3 | GigabitEthernet2 unassigned YES unset administratively down down
4 | GigabitEthernet3 unassigned YES manual administratively down down
5 | VirtualPortGroup0 172.16.126.251 YES unset up up
6 |
--------------------------------------------------------------------------------
/netconf-102/templates/create_subinterface.j2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <{{ base }}>
5 | {{ interface_id }}.{{ vlan_id }}
6 |
7 |
8 | {{ vlan_id }}
9 |
10 |
11 |
12 |
13 |
14 | {{ ip }}
15 | {{ subnet_mask }}
16 |
17 |
18 |
19 | {{ base }}>
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Cisco DevNet Learning Labs: Sample code
2 |
3 | These code examples provide NETCONF samples for network engineer tasks.
4 |
5 | The step-by-step tutorials that work with this code are [Learning Labs](https://developer.cisco.com/learning).
6 |
7 | Contributions are welcome, and we are glad to review changes through pull requests. See [contributing.md](contributing.md) for details.
8 |
9 | ## Contributing
10 |
11 | These samples are for public consumption, so you must ensure that you have the rights to any content that you contribute.
12 |
13 | ## Getting Involved
14 |
15 | * If you'd like to contribute to an existing lab, refer to [contributing.md](contributing.md).
16 | * If you're interested in creating a new Cisco DevNet Learning Lab, please contact a DevNet administrator for guidance.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/netconf-101/screen_scraping.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import re
4 | import sys
5 |
6 |
7 | def main():
8 | """
9 | Open a file called sandbox-nexus9kv-config.txt.
10 | Print each line that matches a regular expression for a hostname route.
11 | """
12 | HOSTNAME = ''
13 | NXOS_HOSTNAME_REGEX = '^hostname (.*)$'
14 | NXOS_DOMAIN_REGEX = '^ip domain-name (.*)$'
15 | with open('sandbox-nexus9kv-config.txt', 'r') as nexus_config:
16 | for line in nexus_config:
17 | if re.match(NXOS_HOSTNAME_REGEX, line):
18 | HOSTNAME = re.search(NXOS_HOSTNAME_REGEX, line).group(1) + '.'
19 | elif re.match(NXOS_DOMAIN_REGEX, line):
20 | HOSTNAME += re.search(NXOS_DOMAIN_REGEX, line).group(1)
21 |
22 | print(HOSTNAME)
23 |
24 | if __name__ == '__main__':
25 | sys.exit(main())
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 |
55 | # Sphinx documentation
56 | docs/_build/
57 |
58 | # PyBuilder
59 | target/
60 |
61 | #Ipython Notebook
62 | .ipynb_checkpoints
63 |
--------------------------------------------------------------------------------
/netconf-102/get_capabilities.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from ncclient import manager
4 | import sys
5 |
6 | # the variables below assume the user is requesting access
7 | # to a IOS-XE device running in the DevNet Always On SandBox
8 | # use the IP address or hostname of your IOS-XE device
9 | HOST = 'ios-xe-mgmt.cisco.com'
10 | # use the NETCONF port for your IOS-XE device
11 | PORT = 10000
12 | # use the user credentials for your IOS-XE device
13 | USER = 'root'
14 | PASS = 'C!sc0123'
15 |
16 |
17 | # create a main() method
18 | def main():
19 | """Main method that prints netconf capabilities of remote device."""
20 | with manager.connect(host=HOST, port=PORT, username=USER, password=PASS,
21 | hostkey_verify=False, device_params={'name': 'default'},
22 | look_for_keys=False, allow_agent=False) as m:
23 |
24 | # print all NETCONF capabilities
25 | print('***Here are the Remote Devices Capabilities***')
26 | for capability in m.server_capabilities:
27 | print(capability)
28 |
29 | if __name__ == '__main__':
30 | sys.exit(main())
31 |
--------------------------------------------------------------------------------
/netconf-101/get_capabilities.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import logging
4 | from ncclient import manager
5 | import sys
6 |
7 |
8 | # the variables below assume the user is requesting access to a
9 | # Nexus device running in VIRL in the DevNet Always On Sandbox
10 | # use the IP address or hostname of your Nexus device
11 | HOST = '172.16.1.82'
12 | # use the NETCONF port for your Nexus device
13 | PORT = 22
14 | # use the user credentials for your Nexus device
15 | USER = 'cisco'
16 | PASS = 'cisco'
17 |
18 |
19 | # create a main() method
20 | def main():
21 | """Main method that prints NETCONF capabilities of remote device."""
22 | with manager.connect(host=HOST, port=PORT, username=USER, password=PASS,
23 | hostkey_verify=False, device_params={'name': 'nexus'},
24 | look_for_keys=False, allow_agent=False) as m:
25 |
26 | # print all NETCONF capabilities
27 | print('***Here are the Remote Devices Capabilities***')
28 | for capability in m.server_capabilities:
29 | print(capability)
30 |
31 | if __name__ == '__main__':
32 | sys.exit(main())
33 |
--------------------------------------------------------------------------------
/netconf-103/interfaces.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Get interface operational state using NETCONF
4 | #
5 | # darien@sdnessentials.com
6 | #
7 |
8 |
9 | class Interface(object):
10 | """Basic Interface object to store information."""
11 | def __init__(self, name, status):
12 | """
13 | Constructor for basic interface class.
14 |
15 | Parameters: name of interface and interface status.
16 | """
17 | # Instantiate an interface with the name and status
18 | self.name = name
19 | self.status = status
20 |
21 | def check_down(self):
22 | """Basic check if interface is down and if so print a warning."""
23 | if self.status == 'down':
24 | print('#############################################')
25 | print("Warning! Interface: {int_name} is DOWN!".format(int_name=self.name))
26 | print('#############################################')
27 |
28 | def prints(self):
29 | """Basic method to print self."""
30 | print("Interface: {int_name} Status: {int_status}".format(int_name=self.name,
31 | int_status=self.status))
32 |
--------------------------------------------------------------------------------
/netconf-102/get_config_csr1000V.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Get configured interfaces using Netconf
4 | #
5 | # darien@sdnessentials.com
6 | #
7 |
8 | from ncclient import manager
9 | import sys
10 | import xml.dom.minidom
11 |
12 |
13 | # the variables below assume the user is requesting access
14 | # to a IOS-XE device running in the DevNet Always On SandBox
15 | # use the IP address or hostname of your IOS-XE device
16 | HOST = 'ios-xe-mgmt.cisco.com'
17 | # use the NETCONF port for your IOS-XE device
18 | PORT = 10000
19 | # use the user credentials for your IOS-XE device
20 | USER = 'root'
21 | PASS = 'C!sc0123'
22 | # XML file to open
23 | FILE = 'get_interfaces.xml'
24 |
25 |
26 | # create a main() method
27 | def get_configured_interfaces():
28 | """Main method that retrieves the interfaces from config via NETCONF."""
29 | with manager.connect(host=HOST, port=PORT, username=USER, password=PASS,
30 | hostkey_verify=False, device_params={'name': 'default'},
31 | allow_agent=False, look_for_keys=False) as m:
32 |
33 | with open(FILE) as f:
34 | return(m.get_config('running', f.read()))
35 |
36 |
37 | def main():
38 | """Simple main method calling our function."""
39 | interfaces = get_configured_interfaces()
40 | print(xml.dom.minidom.parseString(interfaces.xml).toprettyxml())
41 |
42 |
43 | if __name__ == '__main__':
44 | sys.exit(main())
45 |
--------------------------------------------------------------------------------
/netconf-103/screen_scrape_interfaces.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Get interface operational state using screen scraping
4 | #
5 | # darien@sdnessentials.com
6 | #
7 |
8 | from interfaces import Interface
9 | import re
10 | import sys
11 |
12 |
13 | def main():
14 | """
15 | Open a file called show_ip_int_brie.txt.
16 |
17 | Parse through interface data and create an Interface object for each one found.
18 | """
19 | interfaces = []
20 | INTERFACE_REGEX = '^(FastEthernet|GigabitEthernet)([0-9]+) .*(up|down)'
21 | # open the file called 'show_ip_int_brief.txt'
22 | with open('show_ip_int_brief.txt', 'r') as interface_info:
23 | for line in interface_info:
24 | # Iterate over each line and match against the string INTERFACE_REGEX
25 | m = re.match(INTERFACE_REGEX, line)
26 | if m is not None:
27 | # When the line matches the REGEX, create an Interface() object
28 | interface = Interface(m.group(1) + m.group(2), m.group(3))
29 | # Append the interface to the list, so we can iterate over it
30 | interfaces.append(interface)
31 |
32 | # for each interface print the name and status
33 | for interface in interfaces:
34 | interface.prints()
35 |
36 | # call the check_down() function to print any interfaces in the down state with a warning
37 | for interface in interfaces:
38 | interface.check_down()
39 |
40 | if __name__ == '__main__':
41 | sys.exit(main())
42 |
--------------------------------------------------------------------------------
/netconf-102/get_hostname.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | # import the ncclient library
4 | from ncclient import manager
5 | import sys
6 | import xml.dom.minidom
7 |
8 |
9 | # the variables below assume the user is requesting
10 | # access to a Nexus device running in VIRL in the
11 | # DevNet Always On SandBox
12 | # use the IP address or hostname of your Nexus device
13 | HOST = '172.16.1.82'
14 | # use the NETCONF port for your Nexus device
15 | PORT = 22
16 | # use the user credentials for your Nexus device
17 | USER = 'cisco'
18 | PASS = 'cisco'
19 |
20 |
21 | # create a main() method
22 | def main():
23 | """Main method that retrieves the hostname from config via NETCONF (NXOS)."""
24 | with manager.connect(host=HOST, port=PORT, username=USER, password=PASS,
25 | hostkey_verify=False, device_params={'name': 'nexus'},
26 | allow_agent=False, look_for_keys=False) as m:
27 |
28 | # XML filter to issue with the get operation
29 | hostname_filter = '''
30 |
31 |
32 |
33 |
34 | '''
35 |
36 | result = m.get(('subtree', hostname_filter))
37 | # Pass the XML result as a string to the parseString function
38 | xml_doc = xml.dom.minidom.parseString(result.xml)
39 | hostname = xml_doc.getElementsByTagName("mod:hostname")
40 | print(hostname[0].firstChild.nodeValue)
41 |
42 |
43 | if __name__ == '__main__':
44 | sys.exit(main())
45 |
--------------------------------------------------------------------------------
/netconf-102/configuration_data_randomizer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Randomize a VLAN ID and address to run
4 | # create_subinterface.py against the CSR1000V
5 | # in the Always On SandBox
6 | #
7 | # darien@sdnessentials.com
8 | #
9 |
10 | import argparse
11 | import netaddr
12 | import random
13 | import sys
14 |
15 |
16 | # base prefix to pick random address
17 | ADDR_BASE = '1.0.0.0/20'
18 | # base prefix to pick random route
19 | ROUTE_BASE = '1.1.0.0/20'
20 | # prefix length of resulting random route
21 | LENGTH = 31
22 |
23 |
24 | def random_vlan():
25 | """Return random VLAN ID."""
26 | return random.choice(range(1, 4095))
27 |
28 |
29 | def random_address(base):
30 | """Return a random address based on a base prefix."""
31 | prefix = netaddr.IPNetwork(base)
32 | addresses = netaddr.IPSet(prefix)
33 | for address in [prefix.network, prefix.broadcast]:
34 | addresses.remove(address)
35 | return str(random.choice(list(addresses))) + '/' + str(prefix.prefixlen)
36 |
37 |
38 | def random_route(base, length):
39 | """Return a random route based on a base prefix and target prefix length."""
40 | ip = netaddr.IPNetwork(base)
41 | routes = list(ip.subnet(length))
42 | return random.choice(routes)
43 |
44 |
45 | def main():
46 | """Main method to randomize example configuration data."""
47 | parser = argparse.ArgumentParser()
48 | parser.add_argument('--addr_base', '-a', default=ADDR_BASE, help="base prefix to pick address")
49 | parser.add_argument('--route_base', '-r', default=ROUTE_BASE, help="base prefix to subnet")
50 | parser.add_argument('--length', '-l', default=LENGTH, help="prefix length of resulting subnets", type=int)
51 | args = parser.parse_args()
52 | print('################################################')
53 | print('Here is an example way to run the script: ')
54 | print("python create_subinterface.py {v} {a}".format(v=random_vlan(), a=random_address(args.addr_base)))
55 | print('################################################')
56 |
57 |
58 | if __name__ == '__main__':
59 | sys.exit(main())
60 |
--------------------------------------------------------------------------------
/netconf-101/sandbox-nexus9kv-config.txt:
--------------------------------------------------------------------------------
1 | !Command: show running-config
2 | !Time: Tue Feb 2 17:17:16 2016
3 |
4 | version 7.0(3)I2(1)
5 | hostname n9kvswitchfcs
6 | vdc n9kvswitchfcs id 1
7 | limit-resource vlan minimum 16 maximum 4094
8 | limit-resource vrf minimum 2 maximum 4096
9 | limit-resource port-channel minimum 0 maximum 511
10 | limit-resource u4route-mem minimum 248 maximum 248
11 | limit-resource u6route-mem minimum 96 maximum 96
12 | limit-resource m4route-mem minimum 58 maximum 58
13 | limit-resource m6route-mem minimum 8 maximum 8
14 |
15 | feature telnet
16 | feature bash-shell
17 | feature tacacs+
18 | feature interface-vlan
19 |
20 | no password strength-check
21 | username admin password 5 $5$fiej6ToS$O0JczaqOicFm3A.QMegYAmgJoDRV6rADRXDsGQvJbA7 role network-admin
22 | ip domain-lookup
23 | ip domain-name cisco.com
24 | ip host toolserver-devnet.insieme.local 172.31.219.60
25 | tacacs-server key 7 "wawy123"
26 | ip tacacs source-interface Ethernet1/3
27 | tacacs-server timeout 10
28 | tacacs-server deadtime 20
29 | copp profile strict
30 | snmp-server user admin auth md5 0x0ed227360bf8d651be8d7ee949595ee5 priv 0x0ed227360bf8d651be8d7ee949595ee5 localizedkey engineID 128:0:0:9:3:0:80:86:137:173:111
31 | rmon event 1 log trap public description FATAL(1) owner PMON@FATAL
32 | rmon event 2 log trap public description CRITICAL(2) owner PMON@CRITICAL
33 | rmon event 3 log trap public description ERROR(3) owner PMON@ERROR
34 | rmon event 4 log trap public description WARNING(4) owner PMON@WARNING
35 | rmon event 5 log trap public description INFORMATION(5) owner PMON@INFO
36 | ntp server 10.81.254.202 use-vrf management
37 | tacacs-server directed-request
38 |
39 | vlan 1
40 |
41 | vrf context management
42 | ip domain-name abc.inc
43 | ip name-server 171.70.168.183 10.10.10.1 4.2.2.3 8.8.4.4
44 | ip route 0.0.0.0/0 10.10.10.254
45 |
46 | interface Vlan1
47 |
48 | interface Vlan22
49 | no autostate
50 | management
51 |
52 | interface Ethernet1/1
53 | description managed by puppet
54 | no switchport
55 | ip address 1.1.43.43/24
56 |
57 | interface Ethernet1/2
58 |
59 | interface Ethernet1/3
60 |
61 | interface Ethernet1/4
62 |
63 | interface Ethernet1/5
64 |
65 | interface Ethernet1/6
66 |
67 | interface Ethernet1/7
68 |
69 | interface Ethernet1/8
70 |
71 | interface Ethernet1/9
72 |
73 | interface mgmt0
74 | vrf member management
75 | ip address 10.10.10.51/24
76 | line console
77 | line vty
78 | boot nxos bootflash:/nxos.7.0.3.I2.1.bin
79 |
--------------------------------------------------------------------------------
/contributing.md:
--------------------------------------------------------------------------------
1 | # How to contribute to a Learning Lab
2 |
3 | For Learning Labs, there are a few primary ways to help:
4 | - Testing the Learning Lab and then reporting issues in the repo or in the common issues tracking repo
5 | - Using the Issue tracker to report issues or comment that you will work on an issue
6 | - Updating the content in the Learning Lab repo
7 | - Requesting or creating a release
8 | - Contacting DevNet to publish new or updated Learning Labs
9 |
10 | ## Using the issue tracker
11 |
12 | For Learning Labs, there are two potential places to track issues, depending on
13 | whether the repo is a public or private repo.
14 |
15 | For public repo Learning Labs, use the issue tracker in the repo. All Learning Labs repos in the CiscoDevNet organization have a topic of `learning-labs`.
16 |
17 | For private Learning Labs, use the common Issue tracker in the [CiscoDevNet/learning-labs-issues](https://github.com/CiscoDevNet/learning-labs-issues) repo.
18 |
19 | For DevNet Express events, use these Issue tracker repos based on the content track:
20 | * https://github.com/CiscoDevNet/devnet-express-dna-issues
21 | * https://github.com/CiscoDevNet/devnet-express-cc-issues
22 | * https://github.com/CiscoDevNet/devnet-express-dci-issues
23 | * https://github.com/CiscoDevNet/devnet-express-security-issues
24 |
25 | Use the issue tracker to suggest additions, report bugs, and ask questions.
26 | This is also a great way to connect with the developers of the project as well
27 | as others who are interested in this solution.
28 |
29 | Also use the issue tracker to find ways to contribute. Test a lab, find a bug,
30 | log an issue, or offer an update, comment on the issue that you will take on
31 | that effort, then follow the _Changing the Learning Lab content_ guidance below.
32 |
33 | ## Changing the Learning Lab content
34 |
35 | Generally speaking, you should fork the Learning Lab repository, make changes in
36 | your fork, and then submit a pull request (PR). All new content should be tested
37 | to validate that documented tasks work correctly. Additionally, the content
38 | should follow the [Learning Lab Style Guide](https://github.com/CiscoDevNet/devnet-writing-guidelines/wiki/Lab-Style-Guide).
39 |
40 | The [DevNet Writing Guidelines Wiki](https://github.com/CiscoDevNet/devnet-writing-guidelines/wiki)
41 | describes the review and publishing process in detail. Please feel free to request reviews from DevNet contributors you see in the repository and we will review submissions.
42 |
--------------------------------------------------------------------------------
/netconf-103/get_interfaces_csr1000V.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | #
3 | # Get interface operational state using NETCONF
4 | #
5 | # darien@sdnessentials.com
6 | #
7 |
8 | from interfaces import Interface
9 | from ncclient import manager
10 | import re
11 | import sys
12 | import xml.dom.minidom
13 |
14 |
15 | # the variables below assume the user is requesting access
16 | # to a IOS-XE device running in the DevNet Always On SandBox
17 | # use the IP address or hostname of your IOS-XE device
18 | HOST = 'ios-xe-mgmt.cisco.com'
19 | # use the NETCONF port for your IOS-XE device
20 | PORT = 10000
21 | # use the user credentials for your IOS-XE device
22 | USER = 'root'
23 | PASS = 'C!sc0123'
24 | # XML file to open
25 | FILE = 'enable_odm_control.xml'
26 |
27 |
28 | # create a method to retrieve interface operational data
29 | def get_interface_state(host, port, user, passwd, filename):
30 | """Main method that retrieves the interfaces from config via NETCONF."""
31 | with manager.connect(host=host, port=port, username=user, password=passwd,
32 | hostkey_verify=False, device_params={'name': 'default'},
33 | allow_agent=False, look_for_keys=False) as m:
34 |
35 | # open the XML file to enable ODM
36 | with open(filename) as f:
37 | try:
38 | # issue the edit-config operation with the XML config to enable operational data
39 | rpc_reply = m.edit_config(target='running', config=f.read())
40 | except Exception as e:
41 | print("Encountered the following RPC error!")
42 | print(e)
43 | sys.exit()
44 |
45 | # verify ODM is enabled before continuing
46 | if rpc_reply.ok is not True:
47 | print("Encountered a problem when enabling ODM!")
48 | sys.exit()
49 |
50 | try:
51 | # issue the an RPC get while on interfaces-state
52 | rpc_reply = m.get(filter=('subtree', ""))
53 | except Exception as e:
54 | print("Encountered the following RPC error!")
55 | print(e)
56 | sys.exit()
57 |
58 | # verify the RPC get was successful before continuing
59 | if rpc_reply.ok is not True:
60 | print("Encountered a problem when retrieving operational state!")
61 | sys.exit()
62 | else:
63 | # return the RPC reply containing interface data in XML format
64 | return(rpc_reply)
65 |
66 |
67 | def main():
68 | """Simple main method calling our function."""
69 | list_interfaces = []
70 | result = get_interface_state(HOST, PORT, USER, PASS, FILE)
71 | print(xml.dom.minidom.parseString(result.xml).toprettyxml())
72 | # get a list of interfaces by parsing for the element
73 | interfaces = xml.dom.minidom.parseString(result.xml).getElementsByTagName('interface')
74 | # iterate over each instance of the element
75 | for each in interfaces:
76 | # parse out the and nodes when the
77 | # text node contains "GigabitEthernet|FastEthernet"
78 | if re.match('(Gigabit|Fast)Ethernet', each.getElementsByTagName('name')[0].firstChild.nodeValue):
79 |
80 | # instantiate an Interface() object for each instance of an interface
81 | interface = Interface(each.getElementsByTagName('name')[0].firstChild.nodeValue,
82 | each.getElementsByTagName('oper-status')[0].firstChild.nodeValue)
83 | list_interfaces.append(interface)
84 |
85 | # call the prints() method to print the interface data
86 | for each in list_interfaces:
87 | each.prints()
88 |
89 | # call the check_down() method to print each down interface and a warning
90 | for each in list_interfaces:
91 | each.check_down()
92 |
93 |
94 | if __name__ == '__main__':
95 | sys.exit(main())
96 |
--------------------------------------------------------------------------------
/netconf-102/create_subinterface.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Create a VLAN interface on top of a physical interface
4 | # given parameters in code as global vars
5 | # and VLAN / prefix / interface names as arguments
6 | #
7 | # darien@sdnessentials.com
8 | #
9 |
10 | import argparse
11 | from jinja2 import Environment
12 | from jinja2 import FileSystemLoader
13 | from ncclient import manager
14 | import netaddr
15 | import os.path
16 | import re
17 | import sys
18 |
19 |
20 | HOST = 'ios-xe-mgmt.cisco.com'
21 | PORT = 10000
22 | USER = 'root'
23 | PASS = 'C!sc0123'
24 | BASE = 'GigabitEthernet'
25 | INT_ID = '3'
26 | FILE = 'create_subinterface.xml'
27 | TEMPLATE = 'create_subinterface.j2'
28 |
29 |
30 | def create_xml_config(interface_template, xml_file, interface, int_id, vlan, ip, mask):
31 | """Function to render XML document to configure interface from Jinja2."""
32 | # Use the Jinja2 template provided to create the XML config
33 | env = Environment(loader=FileSystemLoader('templates'))
34 | template = env.get_template(interface_template)
35 | rendered = template.render(base=interface, interface_id=int_id,
36 | vlan_id=vlan, ip=ip, subnet_mask=mask)
37 |
38 | # save the results to the XML file passed as an argument
39 | with open(xml_file, "wb") as f:
40 | f.write(rendered)
41 |
42 | # exit if the file hasn't been created
43 | if os.path.isfile(xml_file) is not True:
44 | print("Failed to create the XML config file!")
45 | sys.exit()
46 |
47 |
48 | def create_vlan(host, port, user, password, interface, int_id, vlan, ip, mask, template, config):
49 | """Function to create a subinterface on CSR1000V."""
50 | intfc = re.compile(r'^(\D+)(\d+)$')
51 | m = intfc.match(interface + int_id)
52 | if m is None:
53 | print("Invalid interface name. Valid example: ", BASE)
54 | sys.exit()
55 |
56 | # create the XML configuration issued via NETCONF
57 | create_xml_config(template, config, interface, int_id, vlan, ip, mask)
58 |
59 | # open the NETCONF session
60 | with manager.connect(host=host, port=port, username=user, password=password,
61 | hostkey_verify=False, device_params={'name': 'default'},
62 | allow_agent=False, look_for_keys=False) as m:
63 | with open(config) as f:
64 | try:
65 | # issue the edit-config operation with the XML config
66 | rpc_reply = m.edit_config(target='running', config=f.read())
67 | except Exception as e:
68 | print("Encountered the following RPC error!")
69 | print(e)
70 | sys.exit()
71 |
72 | # validate the RPC Reply returns "ok"
73 | if rpc_reply.ok is not True:
74 | print("Encountered a problem when configuring the device!")
75 | sys.exit()
76 |
77 |
78 | def main():
79 | """Main method to configure a subinterface."""
80 | parser = argparse.ArgumentParser()
81 | parser.add_argument('vlan', help="VLAN number (1-4094)", type=int)
82 | parser.add_argument('prefix', help="IPv4 or IPv6 prefix")
83 | parser.add_argument('--template', '-t', default=TEMPLATE, help="Jinja2 template file name")
84 | parser.add_argument('--config', '-c', default=FILE, help="XML config file name")
85 | parser.add_argument('--interface', '-i', default=BASE, help="interface name to use")
86 | parser.add_argument('--id', '-d', default=INT_ID, help="interface ID to use")
87 | parser.add_argument('--user', '-u', default=USER, help="user name on remote host")
88 | parser.add_argument('--password', '-p', default=PASS, help="password on remote host")
89 | parser.add_argument('--port', '-P', default=PORT, help="port on remote host")
90 | parser.add_argument('--host', '-H', default=HOST, help="remote host")
91 | args = parser.parse_args()
92 |
93 | # check for valid VLAN ID
94 | if args.vlan < 1 or args.vlan > 4094:
95 | parser.print_usage()
96 | print("invalid VLAN ID %s" % str(args.vlan))
97 | sys.exit()
98 |
99 | # check for valid prefix
100 | try:
101 | ip = netaddr.IPNetwork(args.prefix)
102 | except netaddr.core.AddrFormatError as e:
103 | parser.print_usage()
104 | print(e)
105 | sys.exit()
106 |
107 | return create_vlan(args.host, args.port, args.user, args.password, args.interface,
108 | args.id, args.vlan, ip.ip, ip.netmask, args.template, args.config)
109 |
110 |
111 | if __name__ == '__main__':
112 | sys.exit(main())
113 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------