Actions¶
Add a Configuration Block to a Node¶
Objective¶
In order to keep your provisioning data modular, you may want to break apart
configuration blocks into small code blocks. You can use the add_config
action to place a block on code on the node.
Solution¶
Example 1: Add a static block of configuration to your node
First, create a template file with the desired configuration.
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Make sure you have a directory for templates
admin@ztpserver:~# mkdir -p files/templates
# Create a static config block
admin@ztpserver:~# vi files/templates/east-dns.template
!
ip name-server vrf default east.ns1.example.com
!
Then add the add_config
action to your definition:
---
actions:
-
action: add_config
attributes:
url: files/templates/east-dns.template
name: "Add East DNS Server"
Explanation¶
Here we defined a simple action that adds configuration to the node during
provisioning. The url
in this case is relative to [data_root]
/url. It’s
important to realize that the ZTPServer does not compile these configuration
blocks into a startup-config and then send a single file to the node. Rather,
the node executes each action independently, building the configuration in a
module fashion. If you are interested in performing variable substitution in your
templates to make them more flexible, see the next recipe.
Note
Please see the add_config documentation for more details.
Add Configuration to a Node Using Variables¶
Objective¶
I want to keep my templates flexible by using variables. In some cases, I’d like to assign a variable from a resource pool.
Solution¶
First, create a template file with the desired configuration. In this recipe let’s configure interface Management1.
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Make sure you have a directory for templates
admin@ztpserver:~# mkdir -p files/templates
# Create a static config block
admin@ztpserver:~# vi files/templates/ma1.template
Paste this config into the template:
!
interface Management1
ip address $ipaddress
no shutdown
!
Then add the add_config
action to your definition:
---
actions:
-
action: add_config
attributes:
url: files/templates/ma1.template
variables:
ipaddress: allocate("mgmt_subnet")
name: "Configure Ma1"
Then create a resource pool called mgmt_subnet:
# Create a resource pool
admin@ztpserver:~# vi resources/mgmt_subnet
Paste the following into mgmt_subnet
:
192.0.2.10/24: null
192.0.2.11/24: null
192.0.2.12/24: null
192.0.2.13/24: null
Explanation¶
This recipe ties a few different concepts together. From a high-level, the definition
contains an action, add_config
, which references a configuration block, ma1.template
.
Further, we use a variable, $ipaddress
in the template file so that the template
can be used for all nodes being provisioned. The final piece is the use of the
allocate()
plugin, which dynamically assigns a key from the associated
file-based resource pool.
In practice, when a node requests its definition the ZTPServer will execute the
allocate("mgmt_subnet")
plugin and assign a key from the pool.
The ZTPServer will then write the SYSTEM_ID as the value, overwriting null
.
If you wanted to use the assigned value elsewhere in the definition, simply call
allocate(mgmt_subnet)
and the plugin will not assign a new value, rather it
will return the key already assigned. Note that this is an implementation-detail
specific to this particular plugin - other plugins might vary (please read the
associated documentation for each).
The result would look like:
192.0.2.10/24: <SYSTEM_ID>
192.0.2.11/24: null
192.0.2.12/24: null
192.0.2.13/24: null
Note
Please see the add_config documentation for more details.
Replace Entire Startup-Config During Provisioning¶
Objective¶
I have a complete startup-config that I want to apply during provisioning. I want to completely replace what’s already on the node.
Solution¶
First, create the startup-config with the desired configuration.
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Make sure you have a directory for templates
admin@ztpserver:~# mkdir -p files/configs
# Create a startup-config
admin@ztpserver:~# vi files/configs/tor-startup-config
!
hostname test-node-1
ip name-server vrf default <DNS-SERVER-IP>
!
ntp server <NTP-SERVER-IP>
!
username admin privilege 15 role network-admin secret admin
!
interface Management1
ip address <MGMT-IP-ADDRESS>/<SUBNET>
!
ip access-list open
10 permit ip any any
!
ip route 0.0.0.0/0 <DEFAULT-GW>
!
ip routing
!
management api http-commands
no shutdown
!
banner login
Welcome to $(hostname)!
This switch has been provisioned using the ZTPServer from Arista Networks
Docs: http://ztpserver.readthedocs.org/
Source Code: https://github.com/arista-eosplus/ztpserver
EOF
!
end
Then add the replace_config
action to your definition:
---
actions:
-
action: replace_config
attributes:
url: files/configs/tor-startup-config
name: "Replace entire startup-config"
Explanation¶
This action simply replaces the startup-config
which lives in /mnt/flash/startup-config
.
Note
Please see the replace_config documentation for more details.
Copy a File to a Node During Provisioning¶
Objective¶
I want to copy a file to the node during the provisioning process and then set its permissions.
Solution¶
In this example we’ll copy a python script to the node and set its permissions.
---
actions:
-
action: copy_file
always_execute: true
attributes:
dst_url: /mnt/flash/
mode: 777
overwrite: if-missing
src_url: files/automate/bgpautoinf.py
name: "automate BGP peer interface config"
Explanation¶
Here we add the copy_file
action to our definition. The attributes listed in
the action will be passed to the node so that it is able to retrieve the script
from [SERVER_URL]/files/automate/bgpautoinf.py
. Since we are using overwrite: if-missing
,
the action will only copy the file to the node if it does not already exist.
You could define the url
as any destination the node can reach during provisioning - the
file does not need to exist on the ZTPServer.
Note
Please see the copy_file documentation for more details.
Install a Specific EOS Image¶
Objective¶
I want a specific (v)EOS version to be automatically installed when I provision my node.
Note
This assumes that you’ve already downloaded the desired (v)EOS image from Arista.
Solution¶
Let’s create a place on the ZTPServer to host some SWIs:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create an images directory
admin@ztpserver:~# mkdir -p files/images
# SCP your SWI into the images directory, name it whatever you like
admin@ztpserver:~# scp admin@otherhost:/tmp/vEOS.swi files/images/vEOS_4.14.5F.swi
Now let’s create a definition that performs the install_image
action:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create a definition file
admin@ztpserver:~# vi definitions/tor-definition
Add the following lines to your definition, changing values where needed:
---
name: static node definition
actions:
-
action: install_image
always_execute: true
attributes:
url: files/images/vEOS_4.14.5F.swi
version: 4.14.5F
name: "Install 4.14.5F"
Note
The definition uses YAML syntax
Explanation¶
In this case we are hosting the SWI on the ZTPServer, so we just define the url
in relation
to the data_root
. We could change the url
to point to another server
altogether - the choice is yours. The benefit of hosting the file on the
ZTPServer is that we perform an extra checksum step to validate the integrity of
the file.
In practice, the node requests its definition during the provisioning process. It
sees that it’s supposed to perform the install_image
action, so it
requests the install_image
python script. It then performs an HTTP GET for
the url
. Once it has these locally, it executes the
install_image
script.
Install a Specific EOS Image without downgrading newer systems¶
Objective¶
I want a specific (v)EOS version to be automatically installed when I provision my node but I don’t want systems with newer EOS versions to be downgraded
Note
This assumes that you’ve already downloaded the desired (v)EOS image from Arista.
Solution¶
Let’s create a place on the ZTPServer to host some SWIs:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create an images directory
admin@ztpserver:~# mkdir -p files/images
# SCP your SWI into the images directory, name it whatever you like
admin@ztpserver:~# scp admin@otherhost:/tmp/vEOS.swi files/images/vEOS_4.14.5F.swi
Now let’s create a definition that performs the install_image
action:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create a definition file
admin@ztpserver:~# vi definitions/tor-definition
Add the following lines to your definition, changing values where needed. Specifically note the downgrade: false
attribute.
---
name: static node definition
actions:
-
action: install_image
attributes:
downgrade: false
url: files/images/vEOS_4.17.1F.swi
version: 4.17.1F
name: "Install 4.17.1F"
Note
The definition uses YAML syntax
Explanation¶
The difference between this recipe and the one, above, is setting the downgrade
attribute to false
. When downgrades are disabled, an image will only be copied if the running image is older than the image in the ZTP configuration.
Install an Extension¶
Objective¶
I want to install an extension on my node automatically.
Solution¶
Let’s create a place on the ZTPServer to host the RPMs:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create an images directory
admin@ztpserver:~# mkdir -p files/rpms
# SCP your SWI into the images directory, name it whatever you like
admin@ztpserver:~# scp admin@otherhost:/tmp/myRPM.rpm files/rpms/myRPM.rpm
Now let’s create a definition that performs the install_extension
action:
# Go to your data_root - by default it's /usr/share/ztpserver
admin@ztpserver:~# cd /usr/share/ztpserver
# Create a definition file
admin@ztpserver:~# vi definitions/tor-definition
Add the following lines to your definition, changing values where needed:
---
name: static node definition
actions:
-
action: install_extension
always_execute: true
attributes:
url: files/rpms/myRPM.rpm
name: "Install myRPM extension"
Note
The definition uses YAML syntax
Explanation¶
The install_extension
will copy the RPM defined in the url
parameter and
copy it to the default extension directory, /mnt/flash/.extensions
Note
Please see the install_extension documentation for more details.