diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index 13f68639f..dbe82ce31 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -293,12 +293,21 @@ class DeviceViewSet(CustomFieldModelViewSet): # TODO: Improve error handling response = OrderedDict([(m, None) for m in napalm_methods]) ip_address = str(device.primary_ip.address.ip) + + # Merge NAPALM_ARGS and form data + optional_args = {} + if settings.NAPALM_ARGS: + optional_args.update(settings.NAPALM_ARGS) + + if device.platform.napalm_optional_args: + optional_args.update(parse_optional_args(device.platform.napalm_optional_args)) + d = driver( hostname=ip_address, username=settings.NAPALM_USERNAME, password=settings.NAPALM_PASSWORD, timeout=settings.NAPALM_TIMEOUT, - optional_args=settings.NAPALM_ARGS + optional_args=optional_args ) try: d.open() @@ -446,3 +455,11 @@ class ConnectedDeviceViewSet(ViewSet): return Response() return Response(serializers.DeviceSerializer(local_interface.device, context={'request': request}).data) + + +# Helper function to parser optional_args +def parse_optional_args(optional_args): + if optional_args is not None: + return {x.split('=')[0].strip(): x.split('=')[1].strip() + for x in optional_args.split(',')} + return {} diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index da8dc0457..e1c19c5b7 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -723,7 +723,7 @@ class PlatformForm(BootstrapMixin, forms.ModelForm): class Meta: model = Platform - fields = ['name', 'slug', 'manufacturer', 'napalm_driver', 'rpc_client'] + fields = ['name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_optional_args', 'rpc_client'] class PlatformCSVForm(forms.ModelForm): diff --git a/netbox/dcim/migrations/0056_platform_napalm_optional_args.py b/netbox/dcim/migrations/0056_platform_napalm_optional_args.py new file mode 100644 index 000000000..ce90ac0ea --- /dev/null +++ b/netbox/dcim/migrations/0056_platform_napalm_optional_args.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.13 on 2018-06-22 19:51 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0055_virtualchassis_ordering'), + ] + + operations = [ + migrations.AddField( + model_name='platform', + name='napalm_optional_args', + field=models.CharField(blank=True, help_text='Comma separated key=value pairs passed via optional_args to the driver.', max_length=200, verbose_name='NAPALM optional arguments'), + ), + ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 39bd4ad3d..144996a28 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -815,6 +815,12 @@ class Platform(models.Model): verbose_name='NAPALM driver', help_text="The name of the NAPALM driver to use when interacting with devices" ) + napalm_optional_args = models.CharField( + max_length=200, + blank=True, + verbose_name='NAPALM optional arguments', + help_text="Comma separated key=value pairs passed via optional_args to the driver." + ) rpc_client = models.CharField( max_length=30, choices=RPC_CLIENT_CHOICES, @@ -822,7 +828,7 @@ class Platform(models.Model): verbose_name="Legacy RPC client" ) - csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver'] + csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_optional_args'] class Meta: ordering = ['name']