An Introduction to Automating Arista Devices with PyeAPI

An Introduction to Automating Arista Devices with PyeAPI

Introduction to PyeAPI

The Python Client for eAPI (pyeapi) is a native Python library wrapper around Arista EOS eAPI. It provides a set of Python language bindings for configuring Arista devices. In this blog post, we will look at how to install pyeapi, some prerequisites and some examples.

The pyeapi library helps interact with Arista devices by offering a convenient way to execute commands and manage configurations. For example, if you need to check existing VLANs on a switch or create a new VLAN, you can do so easily with methods like vlans.values() to list VLANs or vlans.create() to add a new one. In the next section, let's look at the prerequisites and how to install pyeapi.

Prerequisites

To begin using pyeapi, you need to ensure that Python is installed on your system. Then, you can install pyeapi using pip, the Python package installer. Once installed, you’ll also need to configure your Arista device to enable eAPI access and set up the appropriate HTTP/HTTPS configurations. This allows pyeapi to communicate with your Arista devices properly.

Installing PyeAPI

Installing pyeapiis as simple as running pip install pyeapi. As I always recommend, create a virtual environment before installing pip modules to keep them isolated from your other projects. A virtual environment is like a separate space on your computer that can have its own versions of Python libraries, so changes you make in one project don’t affect another. This way, you can manage dependencies more easily and avoid conflicts. Throughout this post, I'm using Python 3.10.12.

python -m venv venv
source venv/bin/activate

pip install pyeapi

Arista Configurations

Before you can start using pyeapi with your Arista device, you need to make sure the device is properly configured to accept API calls. This involves enabling HTTPS commands to allow secure communication through the API interface. If you're working in a home lab setup and encounter SSL certificate issues, your device may lack a proper certificate. Here are the configuration commands to properly set up your device.

security pki key generate rsa 4096 mykey.pem
security pki certificate generate self-signed my_cert.pem key mykey.pem validity 3650 parameters common-name aggr_01

management security
   ssl profile MY_CUSTOM_PROFILE
  	tls versions 1.2
  	certificate my_cert.pem key mykey.pem

management api http-commands
   protocol https ssl profile MY_CUSTOM_PROFILE
   no shut

Here is a common error you may encounter without certificates.

pyeapi.eapilib.ConnectionError: Socket error during eAPI connection: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] ssl/tls alert handshake failure (_ssl.c:1007)

PyeAPI Directory Structure and Required Files

When setting up your pyeapi environment, it’s good to organize your project directory in a way that makes sense. In the example setup, we’ve created a directory named pyeapi_post.

➜  pyeapi_post tree
.
├── basic.py
└── nodes.conf

1 directory, 2 files

Inside this directory, you should have two key files.

  1. basic.py - This Python script (the file name can be anything) will contain the actual code to interface with your Arista device using pyeapi.
  2. nodes.conf - This configuration file holds the details of the devices you want to manage. It specifies parameters such as hostname, transport protocol, and credentials.

For a basic setup managing a single device, your nodes.conf file might look something like this.

[connection:aggr_01]
host: 192.168.100.210
transport: https
username: admin
password: admin

If you want to learn more about the configuration file, please check out the official documentation here - https://pyeapi.readthedocs.io/en/latest/configfile.html

Writing your First PyeAPI Script

When starting with network automation, the first thing I try is to see if I can retrieve the running configuration from a device. Let’s give it a try with a simple PyeAPI script.

import pyeapi

pyeapi.load_config('nodes.conf')
node = pyeapi.connect_to('aggr_01')

config = node.get_config('running-config')
print(config)
  1. First, we import the pyeapi library, which is of course required for working with Arista’s EOS devices.
  2. The pyeapi.load_config('nodes.conf') line loads the configuration settings from the file named nodes.conf. This file contains connection details for the network devices we want to manage, such as IP addresses and credentials.
  3. Next, we create a connection to a specific device using pyeapi.connect_to('aggr_01'), where aggr_01 is the identifier for the device as specified in nodes.conf.
  4. Once connected, we use the node.get_config('running-config') method to fetch the device’s running configuration.
  5. Finally, we print the configuration to the console with print(config).

The output you get is a list of lines from the running config, now we know our script works and it can talk to the network device.

['! Command: show running-config', '! device: aggr-01 (cEOSLab, EOS-4.28.10.1M-35010112.428101M (engineering build))', '!', 'no aaa root', '!', 'username admin privilege 15 role network-admin secret sha512 $6$z0/dKt.vUMV4Dkoc$E/qGD847va/m2trB4BCc0p7yFP51BhU2NgVuP5GL9KzGqsFuPbXVQZ30qIA5Up.MkBWQ57s3rEjqQJN2BJHic1', '!', 'transceiver qsfp default-mode 4x10G', '!', 'service routing protocols model multi-agent', '!', 'hostname aggr-01', '!', 'spanning-tree mode mstp', 'spanning-tree mst 0 priority 4096', '!', 'vlan 5', '   name TEST_VLAN', '!', 'vlan 10,20,30', '!', 'management api http-commands', '   protocol https ssl profile MY_CUSTOM_PROFILE', '   no shutdown', '!', 'management api gnmi', '   transport grpc default', '!', 'management api netconf', '   transport ssh default', '!', 'management security', '   ssl profile MY_CUSTOM_PROFILE', '  	tls versions 1.2', '  	certificate my_cert.pem key mykey.pem', '!', 'interface Port-Channel1', '   switchport trunk allowed vlan 10,20,30', '   switchport mode trunk', '!', 'interface Ethernet3', '   channel-group 1 mode active', '!', 'interface Ethernet4', '   channel-group 1 mode active', '!', 'interface Ethernet5', '   switchport trunk allowed vlan 10,20,30', '   switchport mode trunk', '!', 'interface Ethernet6', '   switchport trunk allowed vlan 10,20,30', '   switchport mode trunk', '!', 'interface Management0', '   ip address 192.168.100.210/24', '!', 'interface Vlan10', '   ip address 10.125.10.2/24', '   vrrp 1 priority-level 110', '   vrrp 1 ipv4 10.125.10.1', '!', 'interface Vlan20', '   ip address 10.125.20.2/24', '   vrrp 1 priority-level 110', '   vrrp 1 ipv4 10.125.20.1', '!', 'interface Vlan30', '   ip address 10.125.30.2/24', '   vrrp 1 priority-level 110', '   vrrp 1 ipv4 10.125.30.1', '!', 'ip routing', '!', 'ip route 0.0.0.0/0 192.168.100.1', '!', 'end', '']

This script is a simple demonstration of how to use PyeAPI to interact with network devices and retrieve their configuration.

VLAN Management with PyeAPI

In this section, we’ll explore another example of how to manage VLANs using PyeAPI. We’re building on what we’ve already covered, like loading configurations and connecting to your device, to focus on specifically managing VLANs.

Retrieve Current VLANs

import pyeapi

pyeapi.load_config('nodes.conf')
node = pyeapi.connect_to('aggr_01')

vlans = node.api('vlans')

for vlan in vlans.values():
	print(vlan)

Here, we use the node.api('vlans') call to access the VLANs of our device. This allows us to interact directly with VLAN configs, which is particularly handy for checking what’s already configured on the switch.

This loop prints each VLAN retrieved from the device. The output from this script will show you details about each VLAN, such as its ID, name and current state. Here from the output, you can see a default VLAN and another one that I created for testing.

{'vlan_id': '1', 'name': 'default', 'state': 'active', 'trunk_groups': []}
{'vlan_id': '5', 'name': 'test', 'state': 'active', 'trunk_groups': []}

If you’re interested in details about a specific VLAN, instead of iterating over all VLANs, you can directly retrieve information about a particular VLAN by using the get method. For example, to check the details of VLAN 5, you would adjust the script as follows.

vlans = node.api('vlans')

print(vlans.get(5))

Creating and Deleting VLANs

Creating and deleting VLANs is as simple as calling the create() and delete() methods on the vlans object. Here are examples for creating VLAN 6 and then deleting it.

import pyeapi

pyeapi.load_config('nodes.conf')
node = pyeapi.connect_to('aggr_01')

vlans.create(6)

For deleting the VLAN:

vlans.delete(6)

You can also configure a specific VLAN using the configure_vlan() method. This method requires two arguments: the VLAN ID and a list of commands.

vlans.configure_vlan(6, ['name VLAN_6', 'private-vlan community primary vlan 10'])
aggr-01#show vlan 6
VLAN  Name                         	Status	Ports
----- -------------------------------- --------- -------------------------------
6 	VLAN_6                       	active

aggr-01#show vlan private-vlan
Primary Secondary Type    	Ports
------- --------- ----------- -------------------------------
10  	6     	community

Managing Interfaces

Just like managing VLANs, you can also manage interface configurations using PyeAPI. Here’s a simple example of how to retrieve all IP interfaces from your device. Before running the script, here’s what the raw output from the device when you issue the command show ip interface brief

aggr-01#show ip interface brief
                                                                              	Address
Interface     	IP Address           	Status   	Protocol       	MTU	Owner  
----------------- ------------------------ ------------ -------------- ---------- -------
Management0   	192.168.100.210/24   	up       	up            	1500      	 
Vlan10        	10.125.10.2/24       	up       	up            	1500      	 
Vlan20        	10.125.20.2/24       	up       	up            	1500      	 
Vlan30        	10.125.30.2/24       	up       	up            	1500

And here is what you get from the script

import pyeapi
from ipdb import set_trace

pyeapi.load_config('nodes.conf')
node = pyeapi.connect_to('aggr_01')

interfaces = node.api('ipinterfaces')

print(interfaces.getall())
{'defaults': {'name': 'defaults', 'address': None, 'mtu': None}, 'Management0': {'name': 'Management0', 'address': '192.168.100.210/24', 'mtu': None}, 'Vlan10': {'name': 'Vlan10', 'address': '10.125.10.2/24', 'mtu': None}, 'Vlan20': {'name': 'Vlan20', 'address': '10.125.20.2/24', 'mtu': None}, 'Vlan30': {'name': 'Vlan30', 'address': '10.125.30.2/24', 'mtu': None}}

Closing Thoughts

You might be wondering where I found the classes and methods used in these examples. All the details are available on the GitHub repository. Once you visit the repository, go to the pyeapi > eapi directory, and you'll see a list of available modules. For example, if you're interested in working with NTP servers, you can open the ntp.py file (view here) to see what methods are available for the NTP object and go from there.

If you're new to Python and want to learn the basics, check out our beginner-friendly course. It's a great resource to get you started with Python programming.

Python Fundamentals Course ➜

Subscribe to our newsletter and stay updated.

Don't miss anything. Get all the latest posts delivered straight to your inbox.
Great! Check your inbox and click the link to confirm your subscription.
Error! Please enter a valid email address!