Difference between revisions of "Juniper ZTP/Homer"

From ppwiki
Jump to navigation Jump to search
Line 141: Line 141:
 
   fout.write((template.render(data)))
 
   fout.write((template.render(data)))
 
   fout.close()
 
   fout.close()
 +
 +
===Running the script===

Revision as of 02:05, 6 February 2023

Goal

In this Tutorial, we are going to setup a ZTP environment to be able to run the basic configuration on a new Juniper switch. Once the basic configuration is done, we will run homer to deploy the switch configuration. If you want to know more about homer please check: https://wikitech.wikimedia.org/wiki/Homer

Prerequisites

For this tutorial I will be using :

- EVE-NG 2.0.3-112

- VQFX model: vqfx-10000 running JUNOS 19.4R1.10

- DHPC/TFTP VM (IP:10.192.16.5/install1001.dfw.labnet)

- Homer VM(IP:10.192.32.17/homer1001.dfw.labnet)

- Netbox VM(IP:10.192.32.3/netbox1001.dfw.labnet)

- DNS server(IP:10.192.16.2/ns0.dfw.labnet)

All the VM's are running on Proxmox 7.3.4

Diagram

Setup and Configuration

The section is the just the section needed to make ztp work.

Note: We will generate the juniper_ztp file using later on a python script

DHCP configuration

#######################################################################
# ZTP Sample Config begins here:
#######################################################################
option option-150 code 150 = ip-address;
set vendor-string = option vendor-class-identifier;
option space ZTP;
option ZTP.image-file-name         code 0 = text;
option ZTP.config-file-name        code 1 = text;
option ZTP.image-file-type         code 2 = text;
option ZTP.transfer-mode           code 3 = text;
option ZTP.alt-imagefile-name      code 4 = text;
option ZTP-encapsulation           code 43 = encapsulate ZTP;
# mgmt nework
subnet 10.193.0.0 netmask 255.255.255.0 {
         authoritative;
         option subnet-mask             255.255.255.0;
         option option-150              10.192.16.5;  #TFTP server
         option routers                 10.193.0.1;
         option broadcast-address       10.193.0.255;
         option domain-name             "mgmt.dfw.labnet";
         default-lease-time             600;
         max-lease-time                 7200;
}
group {
        vendor-option-space ZTP;
        include "/etc/dhcp/juniper_ztp";   
}

DNS entries for the 4 switches

$ORIGIN 0.193.10.in-addr.arpa.
---
101     1H      IN      PTR     lsw1-a1-dfw.mgmt.dfw.labnet.
102     1H      IN      PTR     lsw1-a2-dfw.mgmt.dfw.labnet.
103     1H      IN      PTR     lsw1-a3-dfw.mgmt.dfw.labnet.
104     1H      IN      PTR     lsw1-a4-dfw.mgmt.dfw.labnet.

$ORIGIN mgmt.dfw.labnet.
---
lsw1-a1-dfw      1H      IN      A       10.193.0.101
lsw1-a2-dfw      1H      IN      A       10.193.0.102
lsw1-a3-dfw      1H      IN      A       10.193.0.103
lsw1-a4-dfw      1H      IN      A       10.193.0.104

Script

This Python scrip will read data from a csv file and generate the dhcp_hosts = juniper_ztp file using a template. I am running the script on my homer VM in a NFS directory (see below). The reason i am running it in a NFS directory is to create a symbolic link from the directory to the "/etc/dhcp/juniper_ztp" file mentioned in the dhcpd.conf file.

ppaul@homer1001:/nfs/general/ztp$ ls -l
total 12
-rw-r--r-- 1 nobody nogroup 281 Feb  5 21:34 dhcp_template
-rw-r--r-- 1 nobody nogroup 738 Feb  5 21:36 generate_host.py
-rw-r--r-- 1 nobody nogroup 224 Feb  5 23:31 ztp_host.csv
ppaul@homer1001:/nfs/general/ztp$ 
ppaul@install1001:/etc/dhcp$ ls -la
total 72
drwxr-xr-x  5 root root  4096 Feb  5 23:13 .
drwxr-xr-x 82 root root  4096 Feb  5 23:05 ..
-rw-r--r--  1 root root  1426 May 26  2021 debug
-rw-r--r--  1 root root  1735 May 26  2021 dhclient.conf
drwxr-xr-x  2 root root  4096 Nov  3 23:31 dhclient-enter-hooks.d
drwxr-xr-x  2 root root  4096 Nov  3 23:32 dhclient-exit-hooks.d
-rw-r--r--  1 root root  3331 Oct  4 15:52 dhcpd6.conf
-rw-r--r--  1 root root  6088 Feb  5 01:07 dhcpd.conf
lrwxrwxrwx  1 root root    27 Feb  5 23:13 juniper_ztp -> /nfs/general/ztp/dhcp_hosts 
-rw-r--r--  1 root root 18869 Jan 28 14:29 linux-host-entries
-rw-r--r--  1 root root   794 Nov  3 23:38 linux-vm-entries
 
  • cvs file :ztp_host.csv

In a real world, working with real switches you can get the mgmt interface MAC directly from the sticker on the box the switch came in. You don't have to power on and connect to the switch before getting the information like I did with the VQFX. For the mgmt IP address and the host name you can get those information once the switch is already in Netbox and has an IP.

hostname,mgmt_ip,cidr_bits,mac_address
lsw1-a1-dfw,10.193.0.101,24,50:00:00:0e:00:00
lsw1-a2-dfw,10.193.0.102,24,50:00:00:16:00:00
lsw1-a3-dfw,10.193.0.103,24,50:00:00:17:00:00
lsw1-a4-dfw,10.193.0.104,24,50:00:00:18:00:00
  • template: dhcp_template
host Template:Hostname {
        hardware ethernet Template:Mac address;
        fixed-address Template:Mgmt ip;
        option option-150 "10.192.16.5";
        option host-name "Template:Hostname";
        option ZTP.config-file-name "junos_script.sh";
}
  • python scrip
#!/usr/bin/python3
# Import  modules
import csv
import sys
from jinja2 import Template
# Set variable to your host file path. 
dhcp_file="/nfs/general/ztp/dhcp_hosts"
# Set this variable to the configuration folder
conf_path="/nfs/general/ztp/"
#  csv file name
csv_file="/nfs/general/ztp/ztp_host.csv"
# Read the cvs file and stores the colum headings as a keys
device_data = csv.DictReader(open(csv_file))
# Loops through the device_data csv so we can perform actions for each row
for row in device_data:
 data = row
 with open("dhcp_template") as t_fh:
           t_format = t_fh.read()
 template = Template(t_format)
 fout = open(dhcp_file, 'a')
 print (fout)
 fout.write((template.render(data)))
 fout.close()

Running the script