7 Sept 2024

Why Laravel Might Be the Network Automation Tool You Didn't Know You Needed

Why Laravel Might Be the Network Automation Tool You Didn't Know You Needed

Tired of managing network automation with raw Python scripts? Discover how Laravel, with its built-in scheduling, queues, and web UI support, offers a surprisingly elegant solution for scalable, secure network automation—even in complex environments.

rconfig logo
rconfig logo

rConfig

All at rConfig

laptop php image
laptop php image

When it comes to network automation, many developers and network engineers default to using Python, thanks to its robust libraries like Netmiko, NAPALM, and Paramiko. Python is well-suited for scripting, but it can be a bit tricky when scaling projects, building a user-friendly interface, or managing complex workflows. This is where Laravel, the PHP-based web framework, can offer a compelling alternative.

Laravel's ease of use, extensive ecosystem, and well-organized structure make it surprisingly effective for building network automation tools. In this blog, we’ll walk through how you can get started with Laravel for network automation, and why it might be simpler than building everything from scratch with Python.

Why Laravel for Network Automation?

Laravel offers several advantages for network automation:

  1. Built-In Structure: Laravel’s MVC (Model-View-Controller) architecture organizes your code in a clear way, making it easier to maintain and scale.

  2. Web Interface: Laravel’s Blade templating engine makes it easy to create a clean web UI for your automation platform.

  3. Eloquent ORM: Managing databases and logging network operations becomes easier with Laravel’s built-in ORM (Object Relational Mapping) for working with SQL databases.

  4. Job Queues and Scheduling: Laravel makes it incredibly easy to schedule tasks and queue jobs, essential for automating recurring network operations.

  5. Third-Party Integrations: Laravel’s ecosystem is vast, with plenty of packages for SSH, APIs, and more—simplifying things you’d otherwise write custom code for in Python.

Let’s dive into a simple example of using Laravel to automate network tasks.

Step 1: Install Laravel

To start, you'll need to install Laravel. If you haven’t done that already, you can install it via Composer.

composer global require laravel/installer

After installing Laravel, create a new project:

laravel new network-automation

Once Laravel is installed, navigate into your new project directory:

<span class="hljs-built_in">cd</span> network-automation

Step 2: Set Up SSH for Network Devices

To automate network devices, you need a way to communicate with them. In Python, you would use libraries like Netmiko, but in Laravel, we can use a package like Spatie’s SSH package to easily run SSH commands.

First, install the SSH package:

composer require spatie/ssh

Now, let's create a simple controller that can SSH into a network device and run a command.

Create a New Controller

Run the following Artisan command to generate a controller:

php artisan make:controller NetworkController

This will generate a NetworkController.php file inside app/Http/Controllers/. In this controller, we'll use the Spatie SSH package to automate some tasks.

Code Example: SSH Into a Network Device

Here's how you can SSH into a network device and fetch its configuration:

<span class="hljs-meta"><?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Request</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Spatie</span>\<span class="hljs-title">Ssh</span>\<span class="hljs-title">Ssh</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NetworkController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Controller</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchConfig</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-comment">// SSH credentials</span>
        $ssh = Ssh::create(<span class="hljs-string">'username'</span>, <span class="hljs-string">'192.168.1.1'</span>)
                    ->usePrivateKey(<span class="hljs-string">'/path/to/private_key'</span>)
                    ->execute(<span class="hljs-string">'show running-config'</span>);

        <span class="hljs-comment">// Check if the command was successful</span>
        <span class="hljs-keyword">if</span> ($ssh->wasSuccessful()) {
            $output = $ssh->getOutput();
            <span class="hljs-keyword">return</span> view(<span class="hljs-string">'config.show'</span>, [<span class="hljs-string">'config'</span> => $output]);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> response(<span class="hljs-string">'Failed to fetch config.'</span>, <span class="hljs-number">500</span>

In this example:

  • We’re SSHing into a network device (in this case, 192.168.1.1).

  • The execute('show running-config') command retrieves the running configuration.

  • If successful, the result is passed to a Blade view to be displayed.

Create a Blade View

Let’s create a simple Blade view to show the output of the network device configuration.

Create a new file named show.blade.php in the resources/views/config/ folder.

<!-- resources/views/config/show.blade.php -->
<!DOCTYPE html>
<html lang=<span class="hljs-string">"en"</span>>
<head>
    <meta charset=<span class="hljs-string">"UTF-8"</span>>
    <meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>>
    <title>Device Configuration</title>
</head>
<body>
    <h1>Device Configuration</h1>
    <pre>{{ $config }}</pre>
</body>
</html>

Now, when you navigate to the route connected to this controller method, you’ll see the configuration output in your browser.

Step 3: Define a Route for the Network Controller

Next, set up a route to trigger the controller action. Open routes/web.php and add:

<span class="hljs-keyword">use</span> <span class="hljs-title">App</span>\<span class="hljs-title">Http</span>\<span class="hljs-title">Controllers</span>\<span class="hljs-title">NetworkController</span>;

Route::get(<span class="hljs-string">'/fetch-config'</span>, [NetworkController::class, <span class="hljs-string">'fetchConfig'</span>]);

Now, if you navigate to http://your-app-url/fetch-config, you’ll trigger the SSH command, and the device’s configuration will be displayed in the web UI.

Step 4: Automate Tasks with Laravel’s Task Scheduler

One of the biggest challenges in network automation is scheduling regular tasks, like backups or status checks. Laravel’s built-in task scheduler makes this incredibly easy.

First, let’s set up a recurring task to backup the network device’s configuration every day.

Scheduling a Task

In Laravel, scheduled tasks are defined in the app/Console/Kernel.php file. Open it up and add the following inside the schedule method:

<span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">schedule</span>(<span class="hljs-params">Schedule $schedule</span>)
</span>{
    $schedule->call(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-comment">// SSH into the network device and save the configuration</span>
        $ssh = Ssh::create(<span class="hljs-string">'username'</span>, <span class="hljs-string">'192.168.1.1'</span>)
                    ->usePrivateKey(<span class="hljs-string">'/path/to/private_key'</span>)
                    ->execute(<span class="hljs-string">'show running-config'</span>);

        <span class="hljs-keyword">if</span> ($ssh->wasSuccessful()) {
            $output = $ssh->getOutput();
            \Storage::put(<span class="hljs-string">'backups/network-config-'</span> . now()->format(<span class="hljs-string">'Y-m-d'</span>) . <span class="hljs-string">'.txt'</span>, $output);
        }
    })->daily();
}

This will SSH into the device and save the configuration to a backup file in the storage/app/backups/ directory every day. The scheduler will handle running this job in the background automatically.

Running the Scheduler

To ensure the scheduler runs, you need to add the following cron entry on your server:

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

This will run Laravel’s task scheduler every minute, which in turn will run the defined tasks at the correct time (e.g., daily, weekly, etc.).

Step 5: Use Laravel Queues for Bulk Operations

Network automation often requires running tasks across many devices in parallel. Laravel’s job queues are perfect for this. Let’s say we want to run a command on multiple devices simultaneously—Laravel can queue up the jobs to process them in parallel.

Create a New Job

You can create a job with Artisan:

php artisan make:job RunCommandOnDevice

In the RunCommandOnDevice job, we’ll add the logic to SSH into a device and execute a command.

<span class="hljs-meta"><?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">Jobs</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Spatie</span>\<span class="hljs-title">Ssh</span>\<span class="hljs-title">Ssh</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Bus</span>\<span class="hljs-title">Queueable</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Contracts</span>\<span class="hljs-title">Queue</span>\<span class="hljs-title">ShouldQueue</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Foundation</span>\<span class="hljs-title">Bus</span>\<span class="hljs-title">Dispatchable</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Queue</span>\<span class="hljs-title">InteractsWithQueue</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Queue</span>\<span class="hljs-title">SerializesModels</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RunCommandOnDevice</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ShouldQueue</span>
</span>{
    <span class="hljs-keyword">use</span> <span class="hljs-title">Dispatchable</span>, <span class="hljs-title">InteractsWithQueue</span>, <span class="hljs-title">Queueable</span>, <span class="hljs-title">SerializesModels</span>;

    <span class="hljs-keyword">protected</span> $deviceIp;
    <span class="hljs-keyword">protected</span> $command;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params">$deviceIp, $command</span>)
    </span>{
        <span class="hljs-keyword">$this</span>->deviceIp = $deviceIp;
        <span class="hljs-keyword">$this</span>->command = $command;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params"></span>)
    </span>{
        $ssh = Ssh::create(<span class="hljs-string">'username'</span>, <span class="hljs-keyword">$this</span>->deviceIp)
                    ->usePrivateKey(<span class="hljs-string">'/path/to/private_key'</span>)
                    ->execute(<span class="hljs-keyword">$this</span>->command);

        <span class="hljs-keyword">if</span> ($ssh->wasSuccessful()) {
            <span class="hljs-comment">// Process output or log result</span>
            \Log::info(<span class="hljs-string">'Command successful on '</span> . <span class="hljs-keyword">$this</span>->deviceIp);
        } <span class="hljs-keyword">else</span> {
            \Log::error(<span class="hljs-string">'Command failed on '</span> . <span class="hljs-keyword">$this</span>->deviceIp);
        }
    }
}

Now, you can queue this job for multiple devices:

phpCopy code$devices = [<span class="hljs-string">'192.168.1.1'</span>, <span class="hljs-string">'192.168.1.2'</span>, <span class="hljs-string">'192.168.1.3'</span>];

<span class="hljs-keyword">foreach</span> ($devices <span class="hljs-keyword">as</span> $device) {
    RunCommandOnDevice::dispatch($device, <span class="hljs-string">'show version'</span>);
}

Laravel will queue up these jobs, and you can process them in parallel with workers.

Running the Queue Worker

To start processing the jobs, run the queue worker with:

php artisan queue:work

This allows you to scale up and handle large-scale network automation tasks efficiently.

Conclusion

While Python has been the go-to choice for network automation, Laravel offers a more structured, scalable, and user-friendly solution, especially when building out more complex automation platforms with a UI, scheduling, and job queuing. With packages like Spatie SSH and Laravel’s built-in task scheduling, you can get a powerful network automation platform up and running much faster than starting from scratch with Python.

If you’re building automation tools for larger teams or need a simple way to manage recurring network tasks, Laravel provides an excellent foundation to get

+5

Trusted by Leading Enterprises

Want to see how rConfig can transform your network management?

Contact us today to discuss your specific use case and get expert guidance on securing and optimizing your infrastructure.

An isometric illustration of a person standing on a digital platform beside a staircase, interacting with floating holographic screens, symbolizing technological advancement and data analysis.

+5

Trusted by Leading Enterprises

Want to see how rConfig can transform your network management?

Contact us today to discuss your specific use case and get expert guidance on securing and optimizing your infrastructure.

An isometric illustration of a person standing on a digital platform beside a staircase, interacting with floating holographic screens, symbolizing technological advancement and data analysis.

+5

Trusted by Leading Enterprises

Want to see how rConfig can transform your network management?

Contact us today to discuss your specific use case and get expert guidance on securing and optimizing your infrastructure.

An isometric illustration of a person standing on a digital platform beside a staircase, interacting with floating holographic screens, symbolizing technological advancement and data analysis.