├── Module 2 Python Files
├── Hello World.py
├── inventory.txt
├── Loops.py
├── Files.py
└── Conditionals.py
├── Module 5 Python Files
├── get_interfaces.xml
├── telnetRouter.py
├── sshNetmiko.py
├── sshParamiko.py
├── switchQos.py
├── get_capabilities.py
├── get_interfaces_config.py
└── get_hostname.py
├── README.md
├── Module 3 Python Files
├── Service Ticket.py
├── User.py
└── Host.py
├── Module 4 Python File
└── DEMO-TENANT.py
└── Module 1 Python File
└── Hello World.py
/Module 2 Python Files/Hello World.py:
--------------------------------------------------------------------------------
1 | print("Hello World")
2 |
3 |
--------------------------------------------------------------------------------
/Module 2 Python Files/inventory.txt:
--------------------------------------------------------------------------------
1 | Cisco 3750 Catalyst Switch
2 | Cisco 2960 Catalyst Switch
3 | Cisco 2911 Router
4 | Cisco 7965G IP Phone
--------------------------------------------------------------------------------
/Module 2 Python Files/Loops.py:
--------------------------------------------------------------------------------
1 | x=input("Enter the number to which you wish to count: ")
2 | x=int(x)
3 | y=1
4 | while True:
5 | print(y)
6 | y=y+1
7 | if y>x:
8 | break
9 |
--------------------------------------------------------------------------------
/Module 5 Python Files/get_interfaces.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Module 2 Python Files/Files.py:
--------------------------------------------------------------------------------
1 | file=open("inventory.txt", "a")
2 | while True:
3 | newitem=input("Enter new inventory item: ")
4 | if newitem == "exit":
5 | print("All done!")
6 | break
7 | file.write(newitem + "\n")
8 | file.close
9 |
--------------------------------------------------------------------------------
/Module 2 Python Files/Conditionals.py:
--------------------------------------------------------------------------------
1 | dscp=input("Enter the DSCP value: ")
2 | if dscp=="46":
3 | print("This is a voice media packet.")
4 | elif dscp=="24":
5 | print("This is a voice signaling packet.")
6 | else:
7 | print("This is not a voice packet.")
8 |
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Fundamentals of Network Programmablity Course Files
2 |
3 | The creation of the files in this repository was shown in Kevin Wallace's "Fundamentals of Network Programmability" course.
4 |
5 | The files are provided here as a resource for learners in that course.
6 |
7 | The files are organized into folders corresponding to the course modules in which they were created.
8 |
--------------------------------------------------------------------------------
/Module 5 Python Files/telnetRouter.py:
--------------------------------------------------------------------------------
1 | import getpass
2 | import telnetlib
3 |
4 | HOST = "192.168.1.77"
5 | user = input("Enter your username: ")
6 | password = getpass.getpass()
7 |
8 | tn = telnetlib.Telnet(HOST)
9 |
10 | tn.read_until(b"Username: ")
11 | tn.write(user.encode('ascii') + b"\n")
12 | if password:
13 | tn.read_until(b"Password: ")
14 | tn.write(password.encode('ascii') + b"\n")
15 |
16 | tn.write(b"enable\n")
17 | tn.write(b"cisco\n")
18 | tn.write(b"conf t\n")
19 | tn.write(b"host HQ-ROUTER\n")
20 | tn.write(b"end\n")
21 | tn.write(b"copy run star\n")
22 | tn.write(b"\n")
23 | tn.write(b"exit\n")
24 |
25 | print(tn.read_all().decode('ascii'))
--------------------------------------------------------------------------------
/Module 3 Python Files/Service Ticket.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | requests.packages.urllib3.disable_warnings()
4 |
5 |
6 | CONTROLLER_IP="devnetapi.cisco.com/sandbox/apic_em"
7 |
8 | payload={"username":"devnetuser","password":"Cisco123!"}
9 | url="https://"+CONTROLLER_IP+"/api/v1/ticket"
10 | header={"content-type":"application/json"}
11 |
12 |
13 | response=requests.post(url,data=json.dumps(payload),headers=header,verify=False)
14 |
15 | if(not response):
16 | print("No data returned!")
17 | else:
18 | r_json=response.json()
19 | print(r_json)
20 | ticket=r_json["response"]["serviceTicket"]
21 | print("Ticket: "+ticket)
22 |
23 |
--------------------------------------------------------------------------------
/Module 5 Python Files/sshNetmiko.py:
--------------------------------------------------------------------------------
1 | from netmiko import ConnectHandler
2 |
3 | cat2960 = {
4 | "device_type": "cisco_ios",
5 | "ip": "192.168.1.202",
6 | "username": "cisco",
7 | "password": "cisco",
8 | "secret": "cisco",
9 | }
10 |
11 | net_connect = ConnectHandler(**cat2960)
12 |
13 | net_connect.enable()
14 |
15 | output = net_connect.send_command("show vlan brief")
16 | print (output)
17 |
18 | for vlan in range (10,51,10):
19 | config_commands = ["vlan " + str(vlan), "name Netmiko_VLAN_" + str(vlan)]
20 | output = net_connect.send_config_set(config_commands)
21 | print (output)
22 |
23 | output = net_connect.send_command("show vlan brief")
24 | print (output)
25 |
--------------------------------------------------------------------------------
/Module 5 Python Files/sshParamiko.py:
--------------------------------------------------------------------------------
1 | import paramiko
2 | import time
3 |
4 | HOST = "192.168.1.202"
5 | USER = "cisco"
6 | PASS = "cisco"
7 |
8 | ssh_client = paramiko.SSHClient()
9 | ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
10 | ssh_client.connect(hostname=HOST,username=USER,password=PASS)
11 |
12 | ssh_connection = ssh_client.invoke_shell()
13 |
14 | ssh_connection.send("enable\n")
15 | ssh_connection.send("cisco\n")
16 | ssh_connection.send("conf t\n")
17 |
18 | for vlan in range (10,51,10):
19 | ssh_connection.send("vlan " + str(vlan) + "\n")
20 | ssh_connection.send("name Paramiko_VLAN_" + str(vlan) + "\n")
21 | ssh_connection.send("end\n")
22 |
23 | time.sleep(1)
24 |
25 | output = ssh_connection.recv(11111).decode(encoding="utf-8")
26 |
27 | print(output)
28 |
29 | ssh_client.close
30 |
--------------------------------------------------------------------------------
/Module 5 Python Files/switchQos.py:
--------------------------------------------------------------------------------
1 | import getpass
2 | import telnetlib
3 |
4 | file=open("switches.txt","r")
5 |
6 | for switchIp in file:
7 | switchIp=switchIp.strip()
8 | print("Current switch: "+switchIp)
9 | user = input("Enter your username: ")
10 | password = getpass.getpass()
11 |
12 | tn = telnetlib.Telnet(switchIp)
13 |
14 | tn.read_until(b"Username: ")
15 | tn.write(user.encode('ascii') + b"\n")
16 | if password:
17 | tn.read_until(b"Password: ")
18 | tn.write(password.encode('ascii') + b"\n")
19 |
20 | tn.write(b"enable\n")
21 | tn.write(b"cisco\n")
22 | tn.write(b"conf t\n")
23 | tn.write(b"int range fa 0/1-10\n")
24 | tn.write(b"auto qos voip cisco-phone\n")
25 | tn.write(b"end\n")
26 | tn.write(b"copy run star\n")
27 | tn.write(b"\n")
28 | tn.write(b"exit\n")
29 |
30 | print(tn.read_all().decode('ascii'))
31 |
32 | file.close()
--------------------------------------------------------------------------------
/Module 5 Python Files/get_capabilities.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from ncclient import manager
4 | import sys
5 |
6 |
7 | # the variables below assume the user is leveraging the
8 | # network programmability lab and accessing csr1000v
9 | # use the IP address or hostname of your CSR1000V device
10 | HOST = 'ios-xe-mgmt.cisco.com'
11 | # use the NETCONF port for your IOS-XE device
12 | PORT = 10000
13 | # use the user credentials for your IOS-XE device
14 | USER = 'root'
15 | PASS = 'D_Vay!_10&'
16 |
17 |
18 | # create a main() method
19 | def main():
20 | """
21 | Main method that prints netconf capabilities of remote device.
22 | """
23 | with manager.connect(host=HOST, port=PORT, username=USER,
24 | password=PASS, hostkey_verify=False,
25 | device_params={'name': 'default'},
26 | look_for_keys=False, allow_agent=False) as m:
27 |
28 | # print all NETCONF capabilities
29 | print('***Here are the Remote Devices Capabilities***')
30 | for capability in m.server_capabilities:
31 | print(capability.split('?')[0])
32 |
33 | if __name__ == '__main__':
34 | sys.exit(main())
35 |
--------------------------------------------------------------------------------
/Module 5 Python Files/get_interfaces_config.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env 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 leveraging the
14 | # network programmability lab and accessing csr1000v
15 | # use the IP address or hostname of your CSR1000V 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 = 'D_Vay!_10&'
22 | # XML file to open
23 | FILE = 'get_interfaces.xml'
24 |
25 |
26 | # create a main() method
27 | def get_configured_interfaces(xml_filter):
28 | """
29 | Main method that retrieves the interfaces from config via NETCONF.
30 | """
31 | with manager.connect(host=HOST, port=PORT, username=USER,
32 | password=PASS, hostkey_verify=False,
33 | device_params={'name': 'default'},
34 | allow_agent=False, look_for_keys=False) as m:
35 | with open(xml_filter) as f:
36 | return(m.get_config('running', f.read()))
37 |
38 |
39 | def main():
40 | """
41 | Simple main method calling our function.
42 | """
43 | interfaces = get_configured_interfaces(FILE)
44 | print(xml.dom.minidom.parseString(interfaces.xml).toprettyxml())
45 |
46 | if __name__ == '__main__':
47 | sys.exit(main())
48 |
--------------------------------------------------------------------------------
/Module 3 Python Files/User.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | requests.packages.urllib3.disable_warnings()
4 |
5 |
6 | CONTROLLER_IP="devnetapi.cisco.com/sandbox/apic_em"
7 | GET="get"
8 | POST="post"
9 |
10 | def getServiceTicket():
11 | payload={"username":"devnetuser","password":"Cisco123!"}
12 | url="https://"+CONTROLLER_IP+"/api/v1/ticket"
13 | header={"content-type":"application/json"}
14 |
15 | response=requests.post(url,data=json.dumps(payload),headers=header,verify=False)
16 |
17 | if(not response):
18 | print("No data returned!")
19 | else:
20 | r_json=response.json()
21 | print(r_json)
22 | ticket=r_json["response"]["serviceTicket"]
23 | print("Ticket: "+ticket)
24 | return ticket
25 |
26 | def doRestCall(aTicket,command,url,aData=None):
27 | response_json=None
28 | payload=None
29 | if(aData!=None):
30 | payload=json.dumps(aData)
31 | header={"X-Auth-Token":aTicket,"content-type":"application/json"}
32 | if(command==GET):
33 | r=requests.get(url,data=payload,headers=header,verify=False)
34 | elif(command==POST):
35 | r=requests.post(url,data=payload,headers=header,verify=False)
36 | else:
37 | print("Unknown command!")
38 | return
39 | if(not r):
40 | print("No data returned!")
41 | else:
42 | response_json=r.json()
43 | print(response_json)
44 |
45 | def main():
46 | ticket=getServiceTicket()
47 | if(ticket):
48 | doRestCall(ticket,GET,"https://"+CONTROLLER_IP+"/api/v1/user")
49 | else:
50 | print("no service ticket was received. Ending program!")
51 |
52 | main()
53 |
54 |
--------------------------------------------------------------------------------
/Module 3 Python Files/Host.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | requests.packages.urllib3.disable_warnings()
4 |
5 |
6 | CONTROLLER_IP="devnetapi.cisco.com/sandbox/apic_em"
7 | GET="get"
8 | POST="post"
9 |
10 | def getServiceTicket():
11 | payload={"username":"devnetuser","password":"Cisco123!"}
12 | url="https://"+CONTROLLER_IP+"/api/v1/ticket"
13 | header={"content-type":"application/json"}
14 |
15 | response=requests.post(url,data=json.dumps(payload),headers=header,verify=False)
16 |
17 | if(not response):
18 | print("No data returned!")
19 | else:
20 | r_json=response.json()
21 | ticket=r_json["response"]["serviceTicket"]
22 | return ticket
23 |
24 | def doRestCall(aTicket,command,url,aData=None):
25 | response_json=None
26 | payload=None
27 | if(aData!=None):
28 | payload=json.dumps(aData)
29 | header={"X-Auth-Token":aTicket,"content-type":"application/json"}
30 | if(command==GET):
31 | r=requests.get(url,data=payload,headers=header,verify=False)
32 | elif(command==POST):
33 | r=requests.post(url,data=payload,headers=header,verify=False)
34 | else:
35 | print("Unknown command!")
36 | return
37 | if(not r):
38 | print("No data returned!")
39 | else:
40 | response_json=r.json()
41 | r1=(response_json["response"])
42 | r2=(r1[0])
43 | print("Host IP = "+r2["hostIp"])
44 |
45 | def main():
46 | ticket=getServiceTicket()
47 | if(ticket):
48 | doRestCall(ticket,GET,"https://"+CONTROLLER_IP+"/api/v1/host")
49 | else:
50 | print("no service ticket was received. Ending program!")
51 |
52 | main()
53 |
54 |
--------------------------------------------------------------------------------
/Module 4 Python File/DEMO-TENANT.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | '''
3 | Autogenerated code using arya.py
4 | Original Object Document Input:
5 | {
6 | "imdata": [
7 | {
8 | "fvTenant": {
9 | "attributes": {
10 | "descr": "",
11 | "dn": "uni/tn-DEMO",
12 | "name": "DEMO",
13 | "nameAlias": "",
14 | "ownerKey": "",
15 | "ownerTag": ""
16 | },
17 | "children": [
18 | {
19 | "vnsSvcCont": {
20 | "attributes": {}
21 | }
22 | },
23 | {
24 | "fvRsTenantMonPol": {
25 | "attributes": {
26 | "tnMonEPGPolName": ""
27 | }
28 | }
29 | }
30 | ]
31 | }
32 | }
33 | ],
34 | "totalCount": "1"
35 | }
36 |
37 | '''
38 |
39 | # list of packages that should be imported for this code to work
40 | import cobra.mit.access
41 | import cobra.mit.request
42 | import cobra.mit.session
43 | import cobra.model.fv
44 | import cobra.model.pol
45 | import cobra.model.vns
46 | from cobra.internal.codec.xmlcodec import toXMLStr
47 |
48 | # log into an APIC and create a directory object
49 | ls = cobra.mit.session.LoginSession('https://10.10.20.70', 'admin', 'ciscopsdt')
50 | md = cobra.mit.access.MoDirectory(ls)
51 | md.login()
52 |
53 | # the top level object on which operations will be made
54 | polUni = cobra.model.pol.Uni('')
55 |
56 | # build the request using cobra syntax
57 | fvTenant = cobra.model.fv.Tenant(polUni, ownerKey=u'', name=u'DEMO', descr=u'', nameAlias=u'', ownerTag=u'')
58 | vnsSvcCont = cobra.model.vns.SvcCont(fvTenant)
59 | fvRsTenantMonPol = cobra.model.fv.RsTenantMonPol(fvTenant, tnMonEPGPolName=u'')
60 |
61 |
62 | # commit the generated code to APIC
63 | print toXMLStr(polUni)
64 | c = cobra.mit.request.ConfigRequest()
65 | c.addMo(fvTenant)
66 | md.commit(c)
67 |
68 |
--------------------------------------------------------------------------------
/Module 5 Python Files/get_hostname.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env 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 leveraging the
10 | # DEVNET Sandbox CSR1000v Lab
11 | #
12 | # use the IP address or hostname of your CSR1000V device
13 | HOST = 'ios-xe-mgmt.cisco.com'
14 | # use the NETCONF port for your IOS-XE device
15 | PORT = 10000
16 | # use the user credentials for your IOS-XE device
17 | USER = 'root'
18 | PASS = 'D_Vay!_10&'
19 |
20 |
21 | # create a main() method
22 | def main():
23 | """
24 | Main method that retrieves the hostname from config via NETCONF.
25 | """
26 | with manager.connect(host=HOST, port=PORT, username=USER,
27 | password=PASS, hostkey_verify=False,
28 | device_params={'name': 'default'},
29 | allow_agent=False, look_for_keys=False) as m:
30 |
31 | # XML filter to issue with the get operation
32 | # IOS-XE pre-16.2 YANG model called urn:ios
33 | # IOS-XE 16.2 - 16.4 YANG model called http://cisco.com/ns/yang/ned/ios
34 | # IOS-XE 16.5+ YANG model called http://cisco.com/ns/yang/Cisco-IOS-XE-native
35 | hostname_filter = '''
36 |
37 |
38 |
39 |
40 |
41 | '''
42 | result = m.get_config('running', hostname_filter)
43 | xml_doc = xml.dom.minidom.parseString(result.xml)
44 | hostname = xml_doc.getElementsByTagName("hostname")
45 | print(hostname[0].firstChild.nodeValue)
46 |
47 |
48 | if __name__ == '__main__':
49 | sys.exit(main())
50 |
--------------------------------------------------------------------------------
/Module 1 Python File/Hello World.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | requests.packages.urllib3.disable_warnings() # Disable warnings
4 |
5 |
6 | CONTROLLER_IP="devnetapi.cisco.com/sandbox/apic_em"
7 | GET="get"
8 | POST="post"
9 |
10 |
11 | def getServiceTicket():
12 | ticket=None
13 | #specify the username and password which will be included in the data. Replace ‘xxxx’ with
14 | #your username and password
15 | payload = {"username":"devnetuser","password":"Cisco123!"}
16 |
17 | #This is the URL to get the service ticket.
18 | #The base IP call is https://[Controller IP]/api/v1
19 | #The REST function is ‘ticket’
20 | url = "https://" + CONTROLLER_IP + "/api/v1/ticket"
21 |
22 | #Content type must be included in the header
23 | header = {"content-type": "application/json"}
24 |
25 | #Format the payload to JSON and add to the data. Include the header in the call.
26 | #SSL certification is turned off, but should be active in production environments
27 | response= requests.post(url,data=json.dumps(payload), headers=header, verify=False)
28 |
29 | #Check if a response was received. If not, print an error message.
30 | if(not response):
31 | print ("No data returned!")
32 | else:
33 | #Data received. Get the ticket and print to screen.
34 | r_json=response.json()
35 | ticket = r_json["response"]["serviceTicket"]
36 | print ("ticket: ", ticket)
37 | return ticket
38 |
39 | #Make the REST call using the service ticket, command, http url, data for the body (if any)
40 | def doRestCall(aTicket,command,url,aData=None):
41 | response_json=None
42 | payload=None
43 | try:
44 |
45 | #if data for the body is passed in put into JSON format for the payload
46 | if(aData != None):
47 | payload=json.dumps(aData)
48 |
49 | #add the service ticket and content type to the header
50 | header = {"X-Auth-Token": aTicket, "content-type" : "application/json"}
51 | if(command==GET):
52 | r = requests.get(url, data=payload, headers=header, verify=False)
53 | elif(command==POST):
54 | r = requests.post(url, data=payload, headers=header, verify=False)
55 | else:
56 | #if the command is not GET or POST we don’t handle it.
57 | print ("Unknown command!")
58 | return
59 |
60 | #if no data is returned print a message; otherwise print data to the screen
61 | if(not r):
62 | print("No data returned!")
63 | else:
64 | print ("Returned status code: %d" % r.status_code)
65 |
66 | #put into dictionary format
67 | response_json = r.json()
68 | print(response_json)
69 | except:
70 | err = sys.exc_info()[0]
71 | msg_det = sys.exc_info()[1]
72 | print( "Error: %s Details: %s StackTrace: %s" %
73 | (err,msg_det,traceback.format_exc()))
74 |
75 |
76 |
77 | #the main function
78 | def main():
79 | #Call the function to get the service ticket
80 | ticket=getServiceTicket()
81 |
82 | #If ticket received get the users
83 | if(ticket):
84 | #Get user types in the system
85 | doRestCall(ticket,GET, "https://" + CONTROLLER_IP + "/api/v1/user")
86 |
87 | #Create a new application
88 | doRestCall(ticket, POST, "https://" + CONTROLLER_IP + "/api/v1/topology/application",[{"id":"1","description":"cool app","name":"appABC"}])
89 | else:
90 | print("No service ticket was received. Ending program!")
91 |
92 | #Calls the main function to start the application
93 | main()
94 |
--------------------------------------------------------------------------------