{"id":527,"date":"2020-08-24T13:50:56","date_gmt":"2020-08-24T12:50:56","guid":{"rendered":"https:\/\/zed-network.fr\/?p=527"},"modified":"2020-08-24T18:45:39","modified_gmt":"2020-08-24T17:45:39","slug":"how-to-optimize-your-cisco-day-0-with-poap-and-ansible","status":"publish","type":"post","link":"https:\/\/zed-network.fr\/?p=527","title":{"rendered":"How to Optimize Your Cisco Day-0 with POAP and Ansible"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In this article, we will see how to optimize your time during your Day-0 with Cisco Nexus N9K using POAP and Ansible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Topology Overview<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\" id=\"topology\"><img fetchpriority=\"high\" decoding=\"async\" width=\"611\" height=\"342\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-19.png\" alt=\"\" class=\"wp-image-528\" title=\"Topology Overview\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-19.png 611w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-19-300x168.png 300w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In this infrastructure, we have : <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>one Cisco Nexus N9Kv<\/li><li>one Cisco router to split the mgmt Out-Of-Band (OOB) network used by Nexus (interface mgmt 0)<\/li><li>one linux server running on Ubuntu.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The Ubuntu server will run the following services :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>DHCP server to assign IP addresses and return the path for the tftp server<\/li><li>TFTP server to host and deliver the poap python script<\/li><li>SCP and \/ or HTTP server to host and deliver the Nexus images and configuration file<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">We will use two different networks where the router will be the default gateway for each one:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>10.0.1.0\/24 &#8211; GW .254, used for the OOB network<\/li><li>10.0.2.0\/24 &#8211; GW .254, used to host administration tools<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The server will have the IP address 10.0.2.1\/24 and we will use 10.0.1.100\/24 for the Nexus 9Kv.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The network services<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">DHCP server<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For the DHCP server, we will use isc-dhcp-server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can easily install with the following command this package:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apt-get install isc-dhcp-server<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then you need to configure your server. In this topology the router will be a DHCP Relay, that means request from N9Kv will arrive to this server in unicast with the IP (10.0.1.254) on the router. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Router configuration:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">interface Ethernet0\/1\nip address 10.0.1.254 255.255.255.0\nip helper-address 10.0.2.1\nend <\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For the server configuration, we need to add at least a subnet pool for your own network : 10.0.2.0\/24. If you don&#8217;t have a network which listen on your network, the server will not start.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You need also to create a range for your N9Kv : 10.0.1.0\/24. For this range, we will provide :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The default gateway (option routers)<\/li><li>The tftp server (option tftp-server-name)<\/li><li>The file, which should be used on the tftp server (option bootfile-name)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">In this file we will also create one entry for our N9Kv. We will reserve an IP address based on the Serial Number. The S\/N should be prefixed with : \\000.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# cat \/etc\/dhcp\/dhcpd.conf\nddns-update-style none;\n\noption domain-name \"lab\";\ndefault-lease-time 600;\nmax-lease-time 7200;\n\nauthoritative;\n\nlog-facility local7;\n\nsubnet 10.0.1.0 netmask 255.255.255.0 {\n  range 10.0.1.1 10.0.1.180;\n  option routers 10.0.1.254;\n  option tftp-server-name \"10.0.2.1\";\n  option bootfile-name \"\/poap\/poap.py\";\n  ping-check = 1;\n}\n\nsubnet 10.0.2.0 netmask 255.255.255.0 {\n}\n\nhost N9K-POAP {\n  option dhcp-client-identifier \"\\00090IFLAUVL3T\";\n  fixed-address 10.0.1.100;\n  option tftp-server-name \"10.0.2.1\";\n  option bootfile-name \"\/poap\/poap.py\";\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, you can start your server :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# service isc-dhcp-server start\nroot@ubuntu:\/srv\/tftp\/poap# service isc-dhcp-server status\n* isc-dhcp-server.service - ISC DHCP IPv4 server\n   Loaded: loaded (\/lib\/systemd\/system\/isc-dhcp-server.service; enabled; vendor preset: enabled)\n   Active: active (running) since Sun 2020-08-23 21:12:52 EEST; 16h ago\n     Docs: man:dhcpd(8)\n Main PID: 14027 (dhcpd)\n    Tasks: 1\n   Memory: 8.5M\n      CPU: 563ms\n   CGroup: \/system.slice\/isc-dhcp-server.service\n           `-14027 dhcpd -user dhcpd -group dhcpd -f -4 -pf \/run\/dhcp-server\/dhcpd.pid -cf \/etc\/dhcp\/dhcpd.conf\n\nAug 24 13:22:29 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:30 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:39 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:40 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:42 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:58 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:22:59 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:23:00 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\nAug 24 13:23:07 ubuntu systemd[1]: Started ISC DHCP IPv4 server.\nAug 24 13:23:07 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.2.1 from 00:50:00:00:03:00 via ens3: unknown lease 10.0.2.1.\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">TFTP server<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For the TFTP server, we will use atftp. To install it enter the following command :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# apt install atftpd<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">By default the configuration file is located on \/etc\/default\/atftpd. You can setup the path where is located your files.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">USE_INETD=false\nOPTIONS=\"--tftpd-timeout 300 --logfile \/var\/log\/atftpd.log --retry-timeout 5 --mcast-port 1758 --mcast-addr 239.239.239.0-255 --mcast-ttl 1 --maxthread 100 --verbose=7 \/srv\/tftp\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In your case, we will create directories \/srv\/tftp and some other one:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# tree \/srv\n\/srv\n|-- ftp\n|   `-- welcome.msg\n`-- tftp\n    `-- poap\n        |-- conf\n        |   |-- conf.90IFLAUVL3T\n        |   |-- conf.90IFLAUVL3T.md5\n        |-- nxos.9.3.2.bin\n        |-- nxos.9.3.2.bin.md5\n        |-- poap.py\n        `-- poap.py.md5\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can download from git the poap.py file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">https:\/\/github.com\/datacenter\/nexus9000\/blob\/master\/nx-os\/poap\/poap.py<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You have different version. We will describe one after.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">SCP server<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You need also a server to deliver the Nexus images and the configuration file. Prefer to use a secure server like an scp or https server.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here we will simply use opeenssh-server as scp server and create one service account: poap.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can see one poap user, where the homedirectory is located on \/srv\/tftp\/<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">poap:x:1001:1001::\/srv\/tftp\/:<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">poap.py  <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now we have our services, we need to prepare the poap.py script.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this script, we will provide some information:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the target NXOS version<\/li><li>the path where are located the images<\/li><li>the path where are located the configurations<\/li><li>the credential for scp<\/li><li>the mode used to obtain the config file in our case: serial_number<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Extract of the poap.py file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># **** Here are all variables that parametrize this script ****\n# These parameters should be updated with the real values used\n# in your automation environment\n\n# system and kickstart images, configuration: location on server (src) and target (dst)\nn9k_image_version       = \"9.3.2\" # this must match your code version\nimage_dir_src           = \"\/srv\/tftp\/poap\/\"  # Sample - \/Users\/bob\/poap\nftp_image_dir_src_root  = image_dir_src\ntftp_image_dir_src_root = image_dir_src\nn9k_system_image_src    = \"nxos.%s.bin\" % n9k_image_version\nconfig_file_src         = \"\/srv\/tftp\/poap\/conf\/conf\" # Sample - \/Users\/bob\/poap\/conf\nimage_dir_dst           = \"bootflash:\" # directory where n9k image will be stored\nsystem_image_dst        = n9k_system_image_src\nconfig_file_dst         = \"volatile:poap.cfg\"\nmd5sum_ext_src          = \"md5\"\n# Required space on \/bootflash (for config and system images)\nrequired_space          = 350000\n\n# copy protocol to download images and config\n# options are: scp\/http\/tftp\/ftp\/sftp\nprotocol                = \"scp\" # protocol to use to download images\/config\n\n# Host name and user credentials\nusername                = \"poap\" # server account\nftp_username            = \"anonymous\" # server account\npassword                = \"cisco1234\" # password\nhostname                = \"10.0.2.1\" # ip address of ftp\/scp\/http\/sftp server\n\n# vrf info\nvrf = \"management\"\nif os.environ.has_key('POAP_VRF'):\n    vrf=os.environ['POAP_VRF']\n\n# Timeout info (from biggest to smallest image, should be f(image-size, protocol))\nsystem_timeout          = 2100\nconfig_timeout          = 120\nmd5sum_timeout          = 120\n\n# POAP can use 3 modes to obtain the config file.\n# - 'static' - filename is static\n# - 'serial_number' - switch serial number is part of the filename\n# - 'location' - CDP neighbor of interface on which DHCPDISCOVER arrived\n#                is part of filename\n# if serial-number is abc, then filename is $config_file_src.abc\n# if cdp neighbor's device_id=abc and port_id=111, then filename is config_file_src.abc.111\n# Note: the next line can be overwritten by command-line arg processing later\nconfig_file_type        = \"serial_number\"\n\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After you changed something on this file, you need to generate the md5 with the command within the script :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">f=poap.py ; cat $f | sed '\/^#md5sum\/d' &gt; $f.md5 ; sed -i \"s\/^#md5sum=.<em>\/#md5sum=\\\"$(md5sum $f.md5 | sed 's\/ .<\/em>\/\/')\\\"\/\" $f<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You need also to prepare the configuration file. Basically you need to provide the minimum like :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the admin credential<\/li><li>the IP address for the management interface<\/li><li>the default gateway for the management vrf.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">One other recommendation is also to add one other account, which can be used to push the Post-Configuration. In my case, I added one account for ansible with an ssh key.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to do the same, you need to create one new user dedicated for ansible, generated one RSA key and put the public key on your configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#adduser ansible\n#su - ansible\n#ssh-keygen\n\nansible@ubuntu:\/srv\/tftp\/poap# ssh-keygen\nGenerating public\/private rsa key pair.\nEnter file in which to save the key (\/ansible\/.ssh\/id_rsa):\nEnter passphrase (empty for no passphrase):\nEnter same passphrase again:\nYour identification has been saved in \/ansible\/.ssh\/id_rsa.\nYour public key has been saved in \/ansible\/.ssh\/id_rsa.pub.\nThe key fingerprint is:\nSHA256:9YHPgARV1M1o0OhO\/XLPiRqFBnqP+aIY3AXdWxwZqKQ root@ubuntu\nThe key's randomart image is:\n+---[RSA 2048]----+\n| .ooo+=.<em>o | | ..ooo<\/em>.+ |\n| .++=+.o |\n| Eoo+==. |\n| .S= ++o |\n| . . o * o o |\n| o . o o o.o.|\n| o .. .. .o|\n| . .. .o. |\n+----[SHA256]-----+<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then get the public key on the following file <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ansible@ubuntu:~\/ansible$ cat ~\/.ssh\/id_rsa.pub\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPcNuuldpLiBuII9obYQXxRJKyqDoIsJAEWDo8w7Wk0bF8Y1A\/Yba4Ld2a61k9NYUy8BbwF7ra3sRM1sd\/lzW4KEsFx0lMq5SFXYBQCeYVSWSstRnuRuspfyQzcGYnPziyolBcDKTpMRekZk3cGD7lWSq32uIKEIW4k5UCywxqXP0RsjlGedtRg2in5tDPn4+qaTGpPRqYN\/Cicoivm4SaX4iFtPhTyGdingss9aMMahdSKK4G1EixQnAfTcotY0A409013a1xuiMetBq+wXgCC19mepwwvovWm825q5CH8xTu9JxzvfolXHKNKIeUxFoQo55MNRgte7RNTC0EtYx9 ansible@ubuntu<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and add it on your Nexus configuration file. You will be able to connect in ssh without password on th Nexus 9K.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[..]\nusername ansible password 5 ! role network-operator\nusername ansible role network-admin\nusername ansible sshkey ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPcNuuldpLiBuII9obYQXxRJKyqDoIsJAEWDo8w7Wk0bF8Y1A\/Yba4Ld2a61k9NYUy8BbwF7ra3sRM1sd\/lzW4KEsFx0lMq5SFXYBQCeYVSWSstRnuRuspfyQzcGYnPziyolBcDKTpMRekZk3cGD7lWSq32uIKEIW4k5UCywxqXP0RsjlGedtRg2in5tDPn4+qaTGpPRqYN\/Cicoivm4SaX4iFtPhTyGdingss9aMMahdSKK4G1EixQnAfTcotY0A409013a1xuiMetBq+wXgCC19mepwwvovWm825q5CH8xTu9JxzvfolXHKNKIeUxFoQo55MNRgte7RNTC0EtYx9 ansible@ubuntu\nusername ansible passphrase lifetime 99999 warntime 14 gracetime 3\n[..]<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">POAP process<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At this time your Cisco Nexus device is probably up and loop in the poap.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">..2020 Aug 24 08:04:39 %$ VDC-1 %$ %CARDCLIENT-2-FPGA_BOOT_GOLDEN: IOFPGA booted from Golden\n2020 Aug 24 08:04:39 %$ VDC-1 %$ %CARDCLIENT-2-FPGA_BOOT_STATUS: Unable to retrieve MIFPGA boot status\n..System is coming up \u2026 Please wait \u2026\n\u2026Starting Auto Provisioning \u2026\n2020 Aug 24 08:05:13 %$ VDC-1 %$ %VDC_MGR-2-VDC_ONLINE: vdc 1 has come online\nDone\nAbort Power On Auto Provisioning yes\/skip\/no yes - continue with normal setup, skip - bypass password and basic configuration, no - continue with Power On Auto Provisioning [no]:\nAbort Power On Auto Provisioning yes - continue with normal setup, skip - bypass password and basic configuration, no - continue with Power On Auto Provisioning[no]: 2020 Aug 24 08:05:23 switch %$ VDC-1 %$ %POAP-2-POAP_INITED: [90IFLAUVL3T-50:00:00:01:00:07] - POAP process initialized\n2020 Aug 24 08:05:39 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - USB Initializing Success\n2020 Aug 24 08:05:39 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - USB disk not detected\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now your switch will start the process. First it will ask an IP address, the server will answer with some other parameter, basically a tftp-server address and a filename.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the DHCP Discover phase you can see the Serial Number inside one option (61). This option will use to reserve one IP Address.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"544\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-20-1024x544.png\" alt=\"\" class=\"wp-image-529\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-20-1024x544.png 1024w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-20-300x159.png 300w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-20-768x408.png 768w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-20.png 1498w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The server will offer the IP address, etc.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"484\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-21-1024x484.png\" alt=\"\" class=\"wp-image-530\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-21-1024x484.png 1024w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-21-300x142.png 300w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-21-768x363.png 768w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-21.png 1501w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">On the server DHCP side we can see the source is 10.0.1.254, which is the default GW for the mgmt subnet, where we have configure the DHCP Relay.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Aug 24 12:22:54 ubuntu dhcpd[14027]: from the dynamic address pool for 10.0.1.0\/24\nAug 24 12:22:54 ubuntu dhcpd[14027]: uid lease 10.0.1.1 for client 50:00:00:01:00:00 is duplicate on 10.0.1.0\/24\nAug 24 12:22:54 ubuntu dhcpd[14027]: DHCPREQUEST for 10.0.1.100 (10.0.2.1) from 50:00:00:01:00:00 via 10.0.1.254\nAug 24 12:22:54 ubuntu dhcpd[14027]: DHCPACK on 10.0.1.100 to 50:00:00:01:00:00 via 10.0.1.254<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">One the Nexus console we can observe the following logs :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">2020 Aug 24 08:05:40 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: Recieved DHCP offer from server ip - 10.0.2.1\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ last message repeated 1 time\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Using DHCP, valid information received over mgmt0 from 10.0.2.1\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Assigned IP address: 10.0.1.100\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Netmask: 255.255.255.0\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - DNS Server: 10.0.100.1\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Default Gateway: 10.0.1.254\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Script Server: 10.0.2.1\n2020 Aug 24 08:05:48 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Script Name: \/poap\/poap.py\n2020 Aug 24 08:06:00 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - The POAP Script download has started\n2020 Aug 24 08:06:00 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - The POAP Script is being downloaded from [copy tftp:\/\/10.0.2.1\/\/poap\/poap.py bootflash:scripts\/script.sh vrf management ]\n2020 Aug 24 08:06:05 switch %$ VDC-1 %$ %USER-1-SYSTEM_MSG: SWINIT failed. devid:241 inst:0 - t2usd\n2020 Aug 24 08:06:10 switch %$ VDC-1 %$ %POAP-2-POAP_SCRIPT_DOWNLOADED: [90IFLAUVL3T-50:00:00:01:00:07] - Successfully downloaded POAP script file\n2020 Aug 24 08:06:10 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - Script file size 20390, MD5 checksum 89f5b64624dcd4c2350dbece6aaf3bab\n2020 Aug 24 08:06:10 switch %$ VDC-1 %$ %POAP-2-POAP_INFO: [90IFLAUVL3T-50:00:00:01:00:07] - MD5 checksum received from the script file is 89f5b64624dcd4c2350dbece6aaf3bab\n2020 Aug 24 08:06:10 switch %$ VDC-1 %$ %POAP-2-POAP_SCRIPT_STARTED_MD5_VALIDATED: [90IFLAUVL3T-50:00:00:01:00:07] - POAP script execution started(MD5 validated)\n2020 Aug 24 08:07:25 switch %$ VDC-1 %$ %ASCII-CFG-2-CONF_CONTROL: System ready<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If everything is good, you have an IP address and download in TFTP the poap.py script. Next the script will verify if you run the target image and download the configuration in SCP.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"339\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-22-1024x339.png\" alt=\"\" class=\"wp-image-531\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-22-1024x339.png 1024w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-22-300x99.png 300w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-22-768x254.png 768w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-22.png 1459w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"349\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-23-1024x349.png\" alt=\"\" class=\"wp-image-532\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-23-1024x349.png 1024w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-23-300x102.png 300w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-23-768x262.png 768w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-23.png 1453w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, you will reload the device.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2020 Aug 24 09:23:20 switch %$ VDC-1 %$ %USER-1-SYSTEM_MSG: SWINIT failed. devid:241 inst:0  - t2usd\n2020 Aug 24 09:24:53 switch %$ VDC-1 %$ %ASCII-CFG-2-CONF_CONTROL: System ready\n2020 Aug 24 09:25:22 switch %$ VDC-1 %$ %VMAN-2-ACTIVATION_STATE: Successfully activated virtual service 'guestshell+'\n2020 Aug 24 09:25:22 switch %$ VDC-1 %$ %VMAN-2-GUESTSHELL_ENABLED: The guest shell has been enabled. The command 'guestshell' may be used to access it, 'guestshell destroy' to remove it.\n2020 Aug 24 09:27:35 switch %$ VDC-1 %$ %POAP-2-POAP_SCRIPT_EXEC_SUCCESS: &#91;90IFLAUVL3T-50:00:00:01:00:07] - POAP script execution success\n2020 Aug 24 09:27:41 switch %$ VDC-1 %$ %POAP-2-POAP_RELOAD_DEVICE: &#91;90IFLAUVL3T-50:00:00:01:00:07] - Reload device\n2020 Aug 24 09:27:51 switch %$ VDC-1 %$ %VMAN-2-ACTIVATION_STATE: Successfully deactivated virtual service 'guestshell+'\n2020 Aug 24 09:27:53 switch %$ VDC-1 %$ %PLATFORM-2-PFM_SYSTEM_RESET: Manual system restart from Command Line Interface\n&#91;  731.127762] sysrq: SysRq : Resetting\nSysconf checksum failed. Using default values\nWARNING:  No BIOS Info found\nSysconf checksum failed. Using default values\nSysconf checksum failed. Using default values\nSysconf checksum failed. Using default values\nATE0Q1&amp;amp;D2&amp;amp;C1S0=1\nStandalone chassis\ncheck_bootmode: grub2pxe: grub failed, launch ipxe\nTrying to load ipxe\nLoading Application:\n\/Vendor(429bdb26-48a6-47bd-664c-801204061400)\/UnknownMedia(6)\/EndEntire\ncannot load imageFailed to launch ipxe\nCame back to grub, now load efi shell\nTrying to load efishell\nLoading Application:\n\/Vendor(429bdb26-48a6-47bd-664c-801204061400)\/UnknownMedia(6)\/EndEntire\ncannot load imageFailed to launch shell\nTrying to read config file \/boot\/grub\/menu.lst.local from (hd0,4)\n Filesystem type is ext2fs, partition type 0x83\n\nBooting bootflash:\/nxos.9.3.2.bin ...\nBooting bootflash:\/nxos.9.3.2.bin\nTrying diskboot\n Filesystem type is ext2fs, partition type 0x83\nImage valid\n&#91;..]\nInstalling local RPMS\nPatch Repository Setup completed successfully\nBootstrapping via POAP overriding existing startup-config\nCreating \/dev\/mcelog\nStarting mcelog daemon\nINIT: Entering runlevel: 3\nRunning S93thirdparty-script...\n\nPopulating conf files for hybrid sysmgr ...\nStarting hybrid sysmgr ...\ndone\nNetbroker support IS present in the kernel.\ndone\nExecuting Prune clis.\nAug 24 09:31:14 %FW_APP-2-FIRMWARE_IMAGE_LOAD_SUCCESS No Firmware needed for Non SR card.\n2020 Aug 24 09:31:28  %$ VDC-1 %$  %USER-2-SYSTEM_MSG: &lt;&lt;%USBHSD-2-MOUNT>> logflash: online  - usbhsd\n2020 Aug 24 09:31:35  %$ VDC-1 %$  %DAEMON-2-SYSTEM_MSG: &lt;&lt;%ASCII-CFG-2-CONF_CONTROL>> Poap replay \/bootflash\/poap_replay01.cfg - ascii-cfg&#91;31425]\n2020 Aug 24 09:31:53  %$ VDC-1 %$ netstack: Registration with cli server complete\nSystem is coming up ... Please wait ...\n....System is coming up ... Please wait ...\n2020 Aug 24 09:32:46  %$ VDC-1 %$ %USER-2-SYSTEM_MSG: ssnmgr_app_init called on ssnmgr up - aclmgr\n....2020 Aug 24 09:33:06  %$ VDC-1 %$ %USER-0-SYSTEM_MSG: end of default policer - copp\n2020 Aug 24 09:33:06  %$ VDC-1 %$ %COPP-2-COPP_NO_POLICY: Control-plane is unprotected.\nSystem is coming up ... Please wait ...\n2020 Aug 24 09:33:15  %$ VDC-1 %$ %CARDCLIENT-2-FPGA_BOOT_GOLDEN: IOFPGA booted from Golden\n2020 Aug 24 09:33:15  %$ VDC-1 %$ %CARDCLIENT-2-FPGA_BOOT_STATUS: Unable to retrieve MIFPGA boot status\n....System is coming up ... Please wait ...\n.2020 Aug 24 09:33:47  %$ VDC-1 %$ %ASCII-CFG-2-CONFIG_REPLAY_STATUS: Bootstrap Replay Started.\n.2020 Aug 24 09:33:51  %$ VDC-1 %$ %VDC_MGR-2-VDC_ONLINE: vdc 1 has come online\nWaiting for box online to replay poap config\n2020 Aug 24 09:34:09 switch %$ VDC-1 %$ %ASCII-CFG-2-CONFIG_REPLAY_STATUS: Bootstrap Replay Done.\n2020 Aug 24 09:34:31 switch %$ VDC-1 %$ %USER-1-SYSTEM_MSG: SWINIT failed. devid:241 inst:0  - t2usd\n2020 Aug 24 09:35:46 switch %$ VDC-1 %$ %ASCII-CFG-2-CONFIG_REPLAY_STATUS: Ascii Replay Started.\n2020 Aug 24 09:36:19 switch %$ VDC-1 %$ %ASCII-CFG-2-CONFIG_REPLAY_STATUS: Ascii Replay Done.\n2020 Aug 24 09:36:21 switch %$ VDC-1 %$ %ASCII-CFG-2-CONF_CONTROL: System ready\n&#91;########################################] 100%\n2020 Aug 24 09:36:52 switch %$ VDC-1 %$ %VMAN-2-ACTIVATION_STATE: Successfully activated virtual service 'guestshell+'\n2020 Aug 24 09:36:52 switch %$ VDC-1 %$ %VMAN-2-GUESTSHELL_ENABLED: The guest shell has been enabled. The command 'guestshell' may be used to access it, 'guestshell destroy' to remove it.\nCopy complete, now saving to disk (please wait)...\nCopy complete.\nAuto provisioning complete\n\n\n\nUser Access Verification\nswitch login:<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ANSIBLE<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Your switch is UP with the target image and your configuration. Now you are able to continue your setup with ansible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For ansible we have install the latest version with python-pip :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">pip install ansible\nroot@ubuntu:\/srv\/tftp\/poap# pip list\n[..]\n\nansible 2.9.12\ncffi 1.14.2\ncryptography 3.0\necdsa 0.13\nenum34 1.1.10\nhttplib2 0.9.1\nipaddress 1.0.23\nJinja2 2.8\nMarkupSafe 0.23\nnetaddr 0.7.18\nparamiko 1.16.0\npip 20.2.2\npycparser 2.20\npycrypto 2.6.1\nPyYAML 3.11\nsetuptools 20.7.0\nsix 1.10.0\nwheel 0.29.0<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For this lab, we have two files :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>inventory, which contains the variables for your switch<\/li><li>play1.yml, which is your simple playbook<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">ansible@ubuntu:~\/ansible$ tree\n.\n|-- inventory\n`-- play1.yml\n0 directories, 2 files<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">ansible@ubuntu:~\/ansible$ cat inventory\n[N9K]\nN9K1 ansible_host=10.0.1.100  ansible_port=22\n\n[N9K:vars]\nansible_user=ansible\nansible_connection=network_cli\nansible_network_os=nxos\nansible_python_interpreter=\"\/usr\/bin\/env python\"\nansible@ubuntu:~\/ansible$ cat play1.yml\n---\n- name: Setup Nexus Devices\n\n  hosts: all\n  connection: local\n  gather_facts: False\n\n  tasks:\n    - name: configure hostname\n      nxos_config:\n        lines: hostname {{ inventory_hostname }}\n        save_when: modified\n\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This playbook will setup the hostname and replace the variable {{ inventory_hostname }} by the value inside the inventory : N9K1.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We play the playbook and you can see one changed:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"176\" src=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-24-1024x176.png\" alt=\"\" class=\"wp-image-533\" srcset=\"https:\/\/zed-network.fr\/wp-content\/uploads\/image-24-1024x176.png 1024w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-24-300x52.png 300w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-24-768x132.png 768w, https:\/\/zed-network.fr\/wp-content\/uploads\/image-24.png 1204w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The hostname has been changed.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">switch login:\nUser Access Verification\nswitch login:\nUser Access Verification\nN9K1 login: 2020 Aug 24 09:48:06 N9K1 %$ VDC-1 %$ %COPP-2-COPP_NO_POLICY: Control-plane is unprotected.<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you have issue during the poap, the best option is probably to skip the process and the check the log created in bootflash. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example here where the file name for the configuration is not good:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# cat conf\/poap.log.7_26_15\nINFO: Selected config filename (serial_number) : \/srv\/tftp\/poap\/conf\/conf..90IFLAUVL3T\nINFO: free space is 2523696 kB\nCLI : terminal dont-ask ; terminal password cisco1234 ; copy scp:\/\/poap@10.0.2.1\/srv\/tftp\/poap\/\/nxos.9.3.2.bin.md5 volatile:nxos.9.3.2.bin.md5.poap_md5 vrf management\nCLI : show file volatile:nxos.9.3.2.bin.md5.poap_md5 | grep -v '^#' | head lines 1 | sed 's\/ .*$\/\/'\nINFO: md5sum 76b01ff1d7243ce035c25becd2634d27 (.md5 file)\nCLI : show file bootflash:\/nxos.9.3.2.bin md5sum\nINFO: md5sum 76b01ff1d7243ce035c25becd2634d27 (recalculated)\nINFO: Same source and destination images\nINFO: Verification passed. (system : 11\/4\/2019)\nINFO: Verification passed.  (system : 11\/4\/2019)\nCLI : terminal dont-ask ; terminal password cisco1234 ; copy scp:\/\/poap@10.0.2.1\/srv\/tftp\/poap\/conf\/conf..90IFLAUVL3T volatile:poap.cfg vrf management\nWARN: Copy Failed: \"\\r\\n\\nError: no such file\n[..]\nERR : aborting\nINFO: cleaning up\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The following shows when it works properly :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@ubuntu:\/srv\/tftp\/poap# cat poap.log.8_6_17\nINFO: Selected config filename (serial_number) : \/srv\/tftp\/poap\/conf\/conf.90IFLAUVL3T\nINFO: free space is 2523664 kB\nCLI : terminal dont-ask ; terminal password cisco1234 ; copy scp:\/\/poap@10.0.2.1\/srv\/tftp\/poap\/\/nxos.9.3.2.bin.md5 volatile:nxos.9.3.2.bin.md5.poap_md5 vrf management\nCLI : show file volatile:nxos.9.3.2.bin.md5.poap_md5 | grep -v '^#' | head lines 1 | sed 's\/ .*$\/\/'\nINFO: md5sum 76b01ff1d7243ce035c25becd2634d27 (.md5 file)\nCLI : show file bootflash:\/nxos.9.3.2.bin md5sum\nINFO: md5sum 76b01ff1d7243ce035c25becd2634d27 (recalculated)\nINFO: Same source and destination images\nINFO: Verification passed. (system : 11\/4\/2019)\nINFO: Verification passed.  (system : 11\/4\/2019)\nCLI : terminal dont-ask ; terminal password cisco1234 ; copy scp:\/\/poap@10.0.2.1\/srv\/tftp\/poap\/conf\/conf.90IFLAUVL3T volatile:poap.cfg vrf management\nINFO: Completed Copy of Config File\nCLI : terminal dont-ask ; terminal password cisco1234 ; copy scp:\/\/poap@10.0.2.1\/srv\/tftp\/poap\/conf\/conf.90IFLAUVL3T.md5 volatile:conf.90IFLAUVL3T.md5.poap_md5 vrf management\nCLI : show file volatile:conf.90IFLAUVL3T.md5.poap_md5 | grep -v '^#' | head lines 1 | sed 's\/ .*$\/\/'\nINFO: md5sum 97a6fd0ffad10c1986a1c89b0e433ae8 (.md5 file)\nCLI : show file volatile:poap.cfg md5sum\nINFO: md5sum 97a6fd0ffad10c1986a1c89b0e433ae8 (recalculated)\nCLI : show system internal platform internal info | grep box_online | sed 's\/[^0-9]*\/\/g'\nINFO: Setting the boot variables\nCLI : config terminal ; boot nxos bootflash:\/nxos.9.3.2.bin\nCLI : copy running-config startup-config\nCLI : copy volatile:poap.cfg scheduled-config\nINFO: Configuration successful\n\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will see how to optimize your time during your Day-0 with Cisco Nexus N9K using POAP and Ansible. Topology Overview In this infrastructure, we have : one Cisco Nexus N9Kv one Cisco router to split the mgmt Out-Of-Band (OOB) network used by Nexus (interface mgmt 0) one linux server running on [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[28,27,4,29,31],"tags":[],"class_list":["post-527","post","type-post","status-publish","format-standard","hentry","category-ansible","category-automation","category-cisco","category-nxos","category-nxos-automation"],"_links":{"self":[{"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/posts\/527","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zed-network.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=527"}],"version-history":[{"count":3,"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/posts\/527\/revisions"}],"predecessor-version":[{"id":536,"href":"https:\/\/zed-network.fr\/index.php?rest_route=\/wp\/v2\/posts\/527\/revisions\/536"}],"wp:attachment":[{"href":"https:\/\/zed-network.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=527"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zed-network.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=527"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zed-network.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=527"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}