This guide follows the youtube -guide of Keith Barker: Enable and Verify RESTCONF with the CLI and Postman.
Use a modern cisco device, not an old c2960
Multilayer | Router |
---|---|
pryl#show version | inc Model Number|IOS XE Cisco IOS XE Software, Version 16.09.04 Model Number : WS-C3650-24PS |
pryl#show vers | incl 4321|IOS XE Cisco IOS XE Software, Version 16.12.08 cisco ISR4321/K9 (1RU) processor with ... |
! MultiLayer Switch version should be
! Cisco IOS XE Software, Version 16.09.04
!
show version | incl IOS XE
conf t
interface vlan 1
! interface gi0/0/0
ip address dhcp
no shutdown
!
ntp server ntp.hv.se
do show ntp ass
!
! PAUSE HERE !! Wait for st=3, not strata 16 !!
!
!
hostname pryl
ip domain name cnap.hv.se
crypto key generate rsa usage-keys modulus 512
! (OBS; mÄste vara default 512)
!
username admin priv 15 secret Network!337
ip http authentication local
! ip http server !! Kan vara bra för att testa, men behövs inte
ip http secure-server
!
end
wr
??debug: web-grÀnssnittet fungerar inte (vit sida) om man Àr inne i conf t !?!
??debug: Om du inte har sparat (wr), sÄ hittar inte web-UI confen, utan börjar frÄn början
??debug: show control-plane host open-ports -- visa att tcp-porten Àr igÄng och lyssnar
??debug: debug ip http ssl error
Find out IP of cisco-unit with the command show ip int bri | inc up
IOS-prompt(config)# restconf
(One single command, no parameters )
After a while, you might get the syslog-message ... restconf server has been notified to start
Before (obviously not working)
C:\Users\cisco>curl -k https://192.168.16.XX/restconf -u "admin:Network!337"
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>Sorry, the page you are looking for is currently unavailable.<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
<p><em>Faithfully yours, nginx.</em></p>
</body>
</html>
Start it (run RESTconf server)
Router#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#restconf
Router(config)#
Dec 6 13:42:26.808: %PSD_MOD-5-DMI_NOTIFY_RESTCONF_START: R0/0: psd: PSD/DMI: restconf server has been notified to start
Dec 6 13:43:08.572: %NDBMAN-5-ACTIVE: R0/0: ndbmand: All data providers active.
Dec 6 13:43:16.770: %DMI-5-NACM_INIT: R0/0: dmiauthd: NACM configuration has been set to its initial configuration.
Dec 6 13:43:22.544: %MODULE_STATE-6-ALL_MODULES_UP: All modules are now on-line.
Dec 6 13:43:22.578: %DMI-5-SYNC_START: R0/0: syncfd: External change to running configuration detected. The running configuration will be synchronized to the NETCONF running data store.
Dec 6 13:43:25.863: %MODULE_STATE-6-ALL_MODULES_UP: All modules are now on-line.
Dec 6 13:43:25.866: %DMI-5-ACTIVE: R0/0: nesd: process is in steady state.
Dec 6 13:43:27.039: %DMI-5-SYNC_COMPLETE: R0/0: syncfd: The running configuration has been synchronized to the NETCONF running data store.
Dec 6 13:43:27.040: %DMI-5-ACTIVE: R0/0: syncfd: process is in steady state.
Router(config)#^Z
Dec 6 13:43:40.941: %SYS-5-CONFIG_I: Configured from console by console
Router#wr
Building configuration...
[OK]
After (now it works)
C:\Users\cisco>curl -k https://192.168.16.XX/restconf -u "admin:Network!337"
<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
<data/>
<operations/>
<yang-library-version>2016-06-21</yang-library-version>
</restconf>
C:\Users\cisco>
https://youtu.be/qeanMXpcHIk?t=411
Make sure your PC is on the same network as your cisco-device. Use IPCONFIG to verify that your IP address starts with 192.168.16...
Start a CommandPrompt (CMD) on your PC and try ONE of the below commands, starting at the top, one by one
at the prompt type curl -k https://192.168.16.XX/restconf -u "admin:Network!337"
, but with the correct IP-number
See the proof-of-concept below
curl -k https://192.168.16.XX/restconf -u "admin:Network!337"
curl -k https://192.168.16.XX/restconf/data/netconf-state/capabilities -u "admin:Network!337"
curl -k https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/ -u "admin:Network!337"
curl -k https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/switch/ -u "admin:Network!337"
curl -k https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/router/ -u "admin:Network!337"
curl -k https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/interface/ -u "admin:Network!337"
^ .../router only works if OSPF is configured (or EIGRP, ...)
Barker YouTube: https://youtu.be/qeanMXpcHIk?t=596 (watch from 9'57")
https://192.168.16.XX/restconf
after [Get]SWITCH (multilayer)
! %2F betyder '/' sÄ 1/0/1 blir 1%2F0%2F1
https://192.168.16.XX/restconf/data/netconf-state/capabilities
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/switch/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface=GigabitEthernet1%2F0%2F1/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface=Loopback0
^^^ GET Loopback0 gives error if it does *not* exist
ROUTER
https://192.168.16.XX/restconf/data/netconf-state/capabilities
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/router/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/router/router-ospf/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-native:native/interface/
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces
! %2F betyder '/' sÄ 0/0/0 blir 0%2F0%2F0
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface=GigabitEthernet0%2F0%2F0
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface=Loopback0
https://192.168.16.XX/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface=Loopback6/ipv6-addrs
https://192.168.16.XX/restconf/data/ietf-interfaces:interfaces/interface=Loopback6
^ .../router only works if OSPF is configured (or EIGRP, ...)
Accept
Value: application/yang-data+json
QUESTION: How do you find information about (GET) physical interfaces and loopbacks?
THEORY: POST creates something new in the device, PUT changes something that already exists in the device
THEORY: What you write in notepad/postman is the "intended" state. What is actually running is the "actual" state. In the end theese two should be the same.
conf t
^Z
and save wr
Content-Type
Value: application/yang-data+json
{
"ietf-interfaces:interface": {
"name": "Loopback5",
"type": "iana-if-type:softwareLoopback",
"enabled": true,
"ietf-ip:ipv4": {
"address": [
{
"ip": "5.5.5.5",
"netmask": "255.255.255.0"
}
]
}
}
}
Find a suitable meny and click generate Python code with you favourite web-library (Requests) imported
Change to the /Body\-tab and paste your JSON-definition of loopback 6 with ip 6.6.6.6
Run your python code on your PC
If you get httpS / SSL krash - this is due to self-signed certificates. Then you have to add "verify=False" to your requests() call. Example:
requests.get('https://kennethreitz.com', verify=False)
Endast för tvÄor Endast NIT-2 kan göra denna uppgift
example:
!
interface GigabitEthernet0/0
vrf forwarding Mgmt-vrf
no ip address
negotiation auto
!
Task 1 Keep the Console-kable in your device, but move the ethernet network cable to a (stolen?) MGMT port
Task 2 Clear the former IP-address by issuing the command no ip address
The device now looses Internet connectivity. "ping 1.1.1.1" does no longer work.
Task 3 (optional) IF the port is "stolen" from an ordinary port; make it a MGMT port with the below commands:
! Make sure that the vrf exists (show vrf); otherwise create it with the following commands:
vrf definition Mgmt-vrf
!
address-family ipv4
exit-address-family
!
address-family ipv6
exit-address-family
!
interface Gig X/Y/Z
no switchport ! if it is a switch; already done in routers
vrf forwarding Mgmt-vrf ! Add interface to VRF
Task 4 Get an IP-address for the MGMT port with the command ip address dhcp
Beware of new IP address from the DHCP server.
Task 5 Test connectivity from the PC to the device; it should work nicely
Task 6 Test connectivity from the device to the PC; it fails miserably !?! Try!!
Task 7 try the following commands instead:
ping vrf Mgmt-vrf 1.1.1.1
show ip route
show ip route vrf Mgmt-vrf
ip tftp source-interface GigabitEthernet0/0 ! Use the MGMT interface
Task 8 For fun: Create a loopback interface with the same IP address using the command "ip address A.B.C.D ..."
This should generate an error-message; or should it not??
If you type ping A.B.C.D, then what are you ping'ing? the loopback or the mgmt interface??
Task 9 Start over from the beginning of this lab; test that RESTconf still works
Frivillig uppgift , men den kan göras av alla
<quote from Flipped-Network Guide> (Spine-Leaf)
"The client ports where we put our servers are also routed ports with IP-addresses in the flipped network. The IP-address of these should hierarchy include Flipped Network (10), a leaf (10.0) the port number (10.0.4) and the default gateway of that LAN (10.0.4.1). Server admins tend to get confused if the direction towards the network isnât dot1 (.1)."
This gives us the configuration in pseudo-code:
foreach { $portno towards server }
interface Gigabit $portno
no switchport
ip address 10.$switchno.$portno.1 255.255.255.0
Translated to Python-code it should read something like:
import requests
def rest_my_port(name, ip) {
url = "http://192.168.16.XX/"
headers = {
'Authorization': 'Basic YWRtaW46Y2lzY28=', # CHANGE PASSWORD /Robert
'Content-Type': 'text/plain'
}
payloadDict = { # Python dictionary-datatype
"name": name, # Use parameter-variable 'name' instead of constant
"type": "iana-if-type:softwareLoopback",
"enabled": "true",
"ietf-ip:ipv4": {
"address": [
{
"ip": ip, # Use parameter-variable 'ip' instead of constant
"netmask": "255.255.255.0"
}
]
},
"ietf-ip:ipv6": { }
}
payload = str(payloadDict) # Convert Dictionary to String (bÀttre: json.dumps() )
payload = payload.replace("'", '\\\"') # Change all single-quotes to backslash+doublequote
response = requests.request("POST", url, headers=headers, data=payload)
print("Response from requests is", response.text)
###############
# MAIN PROGRAM, should be same as "flipped-network pseudo-code" above (Spine-Leaf)
###############
switchno="1" # This is switch 1
for i in range(10,20) {
port = "1/0/" + str(i)
ip = "10." + str(switchno) + "." + str(portno) + ".1"
# insert <REST CODE> here, should make the port "no switchport" ! OR DO IT MANUALLY (conf t)
rest_my_port(port, ip)
print("all done")
The interested reader should create python-code for "<REST CODE>" above
GLHF!
R1# show platform software yang-management process
confd : Running
nesd : Running
syncfd : Running
ncsshd : Not Running
dmiauthd : Running
nginx : Running
ndbmand : Running
pubd : Running