In one of my previous posts, I have presented how to install NAPALM and Salt. While Salt can be installed directly from the SaltStack Repo, very easy, using Salt Bootstrap, NAPALM requires more steps and there are a few system dependencies you may need to consider. For Salt users there’s an easier way to get everything installed using one simple command.
Salt Formulas
Formulas are pre-written Salt States, provided by the Salt community. There are plenty of formulas available unde the SaltStack Formulas GitHub organization. Their installation is easy, well explained in detail here: https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html. Basically all you need to do is write your pillar as specified in the formula; each formula has also a pillar.example
file to help with a structure example for the pillar.
For NAPALM users, there’s a new Salt formula: napalm-install-formula. Using this formula, we can install the system packages very easily, in addition to the PyPi
requirements for the NAPALM drivers. This is also a great way to keep your environment updated, by executing a command as simple as salt-call state.sls napalm_install
(I will explain below).
Regular minions and proxy minions
The major difference between regular minions and proxy minions is that the latter are just one process (per network device managed), able to run from everywhere, as long as they are able to contact the Salt master. To use the napalm-install-formula
, you need to run the salt-minion
on the same machine where you have the proxy minion(s), connected eventually to the same Salt master. This does not bring an extra dependency, the salt-proxy
binary is anyway included in the salt-minion
package; in other words, to be able to run proxy minions, you have already installed the salt-minion
, but it might not be used.
We will need to start the Salt minion, as this is the process managing our server, while the proxy minions manage our network devices.
Configure and start the salt-minion
The regular minion is very simple to be started, less complicated than the proxy:
- Specify the host of the Salt master in the minion configuration file (typically
/etc/salt/minion
or/srv/minion
), under the configuration fieldmaster
. In this example, my minion connects to the Salt master running on the same host (in my lab, I run the proxy minions on the same physical machine as the master):
master: localhost
- Start the minion process:
$ sudo systemctl start salt-minion
- Check the unaccepted keys:
$ sudo salt-key -L
Accepted Keys:
csr1
device1
device2
nxos-spine1
vmx1
Denied Keys:
Unaccepted Keys:
eos
ip-172-31-11-15
Rejected Keys:
We can notice that the minion ip-172-31-11-15
is not accepted yet by the master. Accept the key: $ sudo salt-key -a ip-172-31-11-15
.
In the following examples, ip-172-31-11-15
is the minion ID of the Salt minion that manages the server where the proxies run.
Configure the napalm-install-formula
- The pillar has the following structure:
/etc/salt/pillar/napalm.sls
napalm:
install:
- napalm-iosxr
- napalm-junos
Where we can list the NAPALM drivers we need. To install the complete library, with all the possible drivers, you can simply list napalm
.
- Map the
napalm.sls
pillar defined above to the Salt regular minion, idendified by its ID:
/etc/salt/pillar/top.sls
base:
'ip-172-31-11-15':
- napalm
- Refresh pillar on the local minion:
$ sudo salt-call saltutil.refresh_pillar
local:
True
The previous command is executed from the Salt minion server. When executing from the master side, the equivalent command is: $ sudo salt 'ip-172-31-11-15' saltutil.refresh_pillar
.
- Check that the minion has the right data:
$ sudo salt-call pillar.get napalm:install
local:
- napalm-junos
- napalm-iosxr
-
If you have installed the
napalm-install-formula
correctly, you should be able to execute:$ sudo salt-call state.show_sls napalm_install
. Otherwise, make sure you have the map.jinja and init.sls in a directory callednapalm_install
, under one of the paths listed asfile_roots
in the master configuration. -
Execute a dry run and check the output (this step is not mandatory, but it is a good practice):
$ sudo salt-call state.sls napalm_install test=True
local:
----------
ID: install_napalm_junos_pkgs
Function: pkg.installed
Result: None
Comment: The following packages would be installed/updated: libssl-dev, python-cffi, libxslt1-dev, libffi-dev, python-dev
Started: 11:45:03.200592
Duration: 332.72 ms
Changes:
----------
ID: napalm-junos
Function: pip.installed
Result: None
Comment: Python package napalm-junos is set to be installed
Started: 11:45:03.775327
Duration: 974.406 ms
Changes:
----------
ID: install_napalm_iosxr_pkgs
Function: pkg.installed
Result: None
Comment: The following packages would be installed/updated: libssl-dev, python-cffi, python-dev, libffi-dev
Started: 11:45:04.749919
Duration: 9.268 ms
Changes:
----------
ID: napalm-iosxr
Function: pip.installed
Result: None
Comment: Python package napalm-iosxr is set to be installed
Started: 11:45:04.759294
Duration: 957.672 ms
Changes:
Summary for local
------------
Succeeded: 4 (unchanged=4)
Failed: 0
------------
Total states run: 4
Total run time: 2.274 s
The test mode tells us that there are several system packages to be installed, including libxslt1-dev
, libssl-dev
together with the NAPALM libraries from PyPi, using pip
. As everything looks good, we can go ahead and install:
$ sudo salt-call state.sls napalm_install
local:
----------
ID: install_napalm_junos_pkgs
Function: pkg.installed
Result: True
Comment: 5 targeted packages were installed/updated.
The following packages were already installed: python-pip, libxml2-dev
Started: 11:47:43.398503
Duration: 6123.864 ms
Changes:
----------
libffi-dev:
----------
new:
3.1-2+deb8u1
old:
libffi6:
----------
new:
3.1-2+deb8u1
old:
3.1-2+b2
libssl-dev:
----------
new:
1.0.1t-1+deb8u6
old:
libxslt-dev:
----------
new:
1
old:
libxslt1-dev:
----------
new:
1.1.28-2+deb8u3
old:
python-cffi:
----------
new:
0.8.6-1
old:
python-dev:
----------
new:
2.7.9-1
old:
python-dev:any:
----------
new:
1
old:
----------
ID: napalm-junos
Function: pip.installed
Result: True
Comment: All packages were successfully installed
Started: 11:47:50.485667
Duration: 2536.705 ms
Changes:
----------
napalm-junos==0.11.0:
Installed
----------
ID: install_napalm_iosxr_pkgs
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:47:53.023603
Duration: 4.962 ms
Changes:
----------
ID: napalm-iosxr
Function: pip.installed
Result: True
Comment: All packages were successfully installed
Started: 11:47:53.028663
Duration: 4820.892 ms
Changes:
----------
napalm-iosxr==0.5.1:
Installed
Summary for local
------------
Succeeded: 4 (changed=2)
Failed: 0
------------
Total states run: 4
Total run time: 13.486 s
The state execution correctly setup the environment for NAPALM and upgraded the system dependencies to the latest releases.
From here on, if we need to install another NAPALM driver, but we are unsure about its dependencies, we can simply append it to the install list (in the napalm.sls
pillar), e.g.:
napalm:
install:
- napalm-junos
- napalm-iosxr
- napalm-panos
Then execute the state:
$ sudo salt-call state.sls napalm_install
local:
----------
ID: install_napalm_junos_pkgs
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:52:17.193931
Duration: 323.716 ms
Changes:
----------
ID: napalm-junos
Function: pip.installed
Result: True
Comment: Python package napalm-junos was already installed
All packages were successfully installed
Started: 11:52:17.758566
Duration: 2528.329 ms
Changes:
----------
ID: install_napalm_iosxr_pkgs
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:52:20.287092
Duration: 5.199 ms
Changes:
----------
ID: napalm-iosxr
Function: pip.installed
Result: True
Comment: Python package napalm-iosxr was already installed
All packages were successfully installed
Started: 11:52:20.292391
Duration: 1452.512 ms
Changes:
----------
ID: install_napalm_panos_pkgs
Function: pkg.installed
Result: True
Comment: All specified packages are already installed
Started: 11:52:21.745097
Duration: 5.286 ms
Changes:
----------
ID: napalm-panos
Function: pip.installed
Result: True
Comment: All packages were successfully installed
Started: 11:52:21.750481
Duration: 4880.599 ms
Changes:
----------
napalm-panos==0.4.0:
Installed
Summary for local
------------
Succeeded: 6 (changed=1)
Failed: 0
------------
Total states run: 6
Total run time: 9.196 s
If you are running a large scale network and your proxy minions are distributed across multiple servers, the dependencies installation becomes very stright forward:
$ sudo salt -N proxy-minions-servers state.sls napalm_install
Where proxy-minions-servers
is a node group defined on the master, selecting the servers running the proxy processes.
Ensure you are running the latest versions
Using the Salt schedule subsystem, we can ensure the environment is always up to date, by scheduling the state to be executed at specific intervals. For example, the following minion configuration schedules the napalm_install
state to be executed every Monday, at 10AM:
schedule:
napalm_env:
function: state.sls
arg:
- napalm_install
when:
- Monday 10:00am
Conclusions
Although there are some additional steps to get the formula up and running, on the long run this method will turn to be very handy and a good way to maintain your environment updated. In the NAPALM community, we have agreed to release bugfixes and feature releases as often as possible, so most of the time upgrading to the latest version will probably help. So why not use the Salt schedule to execute the napalm_install
state periodically and ensure your environment is always running the latest versions.