SSH Custom script

362 views
Skip to first unread message

Bogdan Cordos

unread,
Dec 14, 2021, 8:45:14 AM12/14/21
to NetBox
Hi,
I have a working custom script that pulls DHCP stats from my Cisco switches that runs a DHCP server.
I'm not a python developer and need a bit of help.
The script goes as fallow:

************************
from django.utils.text import slugify
from netmiko import ConnectHandler
import netbox.settings
from extras.scripts import *


class RunCommand(Script):
    class Meta:
        name = "Run command on Cisco Devices via SSH"
        description = "Run command on Cisco Devices via SSH"
        field_order = ['input_ip', 'input_command']


    input_ip = StringVar(
        description="Enter the IP Address:"
    )
    CHOICES = (
        ('show ip dhcp pool | i .', 'Show DHCP Pools'),
        ('show ip dhcp binding', 'Show DHCP Bindings')
    )
    input_command = ChoiceVar(
        choices=CHOICES
    )

    def run(self, data, commit):

        cisco1 = {
            "device_type": "cisco_ios",
            "host": data['input_ip'],
            "username": netbox.settings.NAPALM_USERNAME,
            "password": netbox.settings.NAPALM_PASSWORD,
        }

        command = data['input_command']

        with ConnectHandler(**cisco1) as net_connect:
            output = net_connect.send_command(command)

            self.log_success("View the information the in Output tab")
        return ''.join(output)
************************

I would like to replace:
    input_ip = StringVar(
        description="Enter the IP Address:"
    )
with an ObjectVar so I can select a device and use its primary IP.
What modules do I need to import and how should I define this ObjectVar.
I did try different ways based on examples found, but I do struggle with this.

Many thanks

Michael E

unread,
Dec 15, 2021, 3:48:22 AM12/15/21
to NetBox
device = ObjectVar(
model = Device,
query_params = {
'has_primary_ip' : 'True'}
)

This should work for the form. You can access the primary IP address from the webform using -  data['device'].primary_ip . The output of data['device'].primary_ip would be 'x.x.x.x/YY' if ipv4 (I did not test ipv6 but I expect similar output)

However, you may need to tweak your script to strip off the cidr mask appended to the end of the ip address to enable netmiko connect to the device

Bogdan Cordos

unread,
Dec 16, 2021, 11:41:35 AM12/16/21
to NetBox
Thanks, Michael

Your suggestion helped a great deal. I manage to tweak the code in the best way I knew and is working like a charm:
******
from netaddr import *
|
|
        address = data['device'].primary_ip
        clear_address = IPNetwork(str(address))
        input_ip = str(clear_address.ip)
******

Thanks again

Brian Candler

unread,
Dec 16, 2021, 1:03:52 PM12/16/21
to NetBox
On Thursday, 16 December 2021 at 16:41:35 UTC bogdan...@gmail.com wrote:
Thanks, Michael

Your suggestion helped a great deal. I manage to tweak the code in the best way I knew and is working like a charm:
******
from netaddr import *
|
|
        address = data['device'].primary_ip
        clear_address = IPNetwork(str(address))
        input_ip = str(clear_address.ip)

There's a cleaner way:

address = data['device'].primary_ip
input_ip = str(address.ip)

That is, primary_ip is a (Netbox) IPAddress object, and primary_ip.address turns this into an IPNetwork object.

Bogdan Cordos

unread,
Dec 17, 2021, 5:07:53 AM12/17/21
to NetBox
Hi Brian,

I have initially tried your way, however I got:
**********

An exception occurred: AttributeError: 'IPAddress' object has no attribute 'ip'

Traceback (most recent call last):
File "/opt/netbox/netbox/extras/scripts.py", line 430, in _run_script script.output = script.run(data=data, commit=commit)
File "/opt/netbox/netbox/scripts/GetDHCPStats.py",
line 42, in run input_ip = str(address.ip)
AttributeError: 'IPAddress' object has no attribute 'ip'

**********
Adding the line "clear_address = IPNetwork(str(address))" cleared the error.

Brian Candler

unread,
Dec 17, 2021, 6:46:55 AM12/17/21
to NetBox
Ah, you need address.address.ip

Tested in nbshell with Netbox 3.1.1:

>>> d = Device.objects.get(name="modem")
>>> d.primary_ip
<IPAddress: 192.168.2.1/24>
>>> d.primary_ip.address
IPNetwork('192.168.2.1/24')
>>> d.primary_ip.address.ip
IPAddress('192.168.2.1')
>>>


Bogdan Cordos

unread,
Dec 17, 2021, 6:52:51 AM12/17/21
to NetBox
Yes, "address.address.ip" works fine.

Thank you, Brian
Reply all
Reply to author
Forward
0 new messages