netbox-toolkit-plugin 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. netbox_toolkit_plugin/__init__.py +32 -0
  2. {netbox_toolkit → netbox_toolkit_plugin}/api/serializers.py +71 -35
  3. {netbox_toolkit → netbox_toolkit_plugin}/api/urls.py +3 -3
  4. {netbox_toolkit → netbox_toolkit_plugin}/config.py +80 -73
  5. {netbox_toolkit → netbox_toolkit_plugin}/connectors/factory.py +170 -111
  6. {netbox_toolkit → netbox_toolkit_plugin}/connectors/netmiko_connector.py +242 -179
  7. {netbox_toolkit → netbox_toolkit_plugin}/connectors/scrapli_connector.py +256 -172
  8. netbox_toolkit_plugin/migrations/0001_initial.py +108 -0
  9. netbox_toolkit_plugin/migrations/0002_alter_command_options_alter_command_unique_together_and_more.py +70 -0
  10. {netbox_toolkit → netbox_toolkit_plugin}/migrations/0003_permission_system_update.py +26 -12
  11. {netbox_toolkit → netbox_toolkit_plugin}/migrations/0004_remove_django_permissions.py +27 -29
  12. {netbox_toolkit → netbox_toolkit_plugin}/migrations/0005_alter_command_options_and_more.py +7 -8
  13. {netbox_toolkit → netbox_toolkit_plugin}/migrations/0006_commandlog_parsed_data_commandlog_parsing_success_and_more.py +7 -8
  14. {netbox_toolkit → netbox_toolkit_plugin}/migrations/0007_alter_commandlog_parsing_template.py +6 -4
  15. {netbox_toolkit → netbox_toolkit_plugin}/models.py +31 -32
  16. {netbox_toolkit → netbox_toolkit_plugin}/navigation.py +6 -6
  17. {netbox_toolkit → netbox_toolkit_plugin}/services/command_service.py +188 -128
  18. {netbox_toolkit → netbox_toolkit_plugin}/services/rate_limiting_service.py +104 -97
  19. netbox_toolkit_plugin/tables.py +51 -0
  20. netbox_toolkit_plugin/templates/netbox_toolkit/command.html +108 -0
  21. netbox_toolkit_plugin/templates/netbox_toolkit/command_list.html +12 -0
  22. netbox_toolkit_plugin/templates/netbox_toolkit/commandlog.html +170 -0
  23. netbox_toolkit_plugin/templates/netbox_toolkit/device_toolkit.html +557 -0
  24. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/command.html +5 -5
  25. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/command_list.html +2 -2
  26. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/commandlog.html +2 -2
  27. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/device_toolkit.html +6 -6
  28. netbox_toolkit_plugin/urls.py +38 -0
  29. {netbox_toolkit → netbox_toolkit_plugin}/utils/logging.py +20 -19
  30. {netbox_toolkit → netbox_toolkit_plugin}/views.py +251 -169
  31. {netbox_toolkit_plugin-0.1.0.dist-info → netbox_toolkit_plugin-0.1.1.dist-info}/METADATA +2 -2
  32. netbox_toolkit_plugin-0.1.1.dist-info/RECORD +60 -0
  33. netbox_toolkit_plugin-0.1.1.dist-info/entry_points.txt +2 -0
  34. netbox_toolkit_plugin-0.1.1.dist-info/top_level.txt +1 -0
  35. netbox_toolkit/__init__.py +0 -30
  36. netbox_toolkit/migrations/0001_initial.py +0 -54
  37. netbox_toolkit/migrations/0002_alter_command_options_alter_command_unique_together_and_more.py +0 -66
  38. netbox_toolkit/tables.py +0 -37
  39. netbox_toolkit/urls.py +0 -22
  40. netbox_toolkit_plugin-0.1.0.dist-info/RECORD +0 -56
  41. netbox_toolkit_plugin-0.1.0.dist-info/entry_points.txt +0 -2
  42. netbox_toolkit_plugin-0.1.0.dist-info/top_level.txt +0 -1
  43. {netbox_toolkit → netbox_toolkit_plugin}/admin.py +0 -0
  44. {netbox_toolkit → netbox_toolkit_plugin}/api/__init__.py +0 -0
  45. {netbox_toolkit → netbox_toolkit_plugin}/api/mixins.py +0 -0
  46. {netbox_toolkit → netbox_toolkit_plugin}/api/schemas.py +0 -0
  47. {netbox_toolkit → netbox_toolkit_plugin}/api/views/__init__.py +0 -0
  48. {netbox_toolkit → netbox_toolkit_plugin}/api/views/command_logs.py +0 -0
  49. {netbox_toolkit → netbox_toolkit_plugin}/api/views/commands.py +0 -0
  50. {netbox_toolkit → netbox_toolkit_plugin}/connectors/__init__.py +0 -0
  51. {netbox_toolkit → netbox_toolkit_plugin}/connectors/base.py +0 -0
  52. {netbox_toolkit → netbox_toolkit_plugin}/exceptions.py +0 -0
  53. {netbox_toolkit → netbox_toolkit_plugin}/filtersets.py +0 -0
  54. {netbox_toolkit → netbox_toolkit_plugin}/forms.py +0 -0
  55. {netbox_toolkit → netbox_toolkit_plugin}/migrations/__init__.py +0 -0
  56. {netbox_toolkit → netbox_toolkit_plugin}/search.py +0 -0
  57. {netbox_toolkit → netbox_toolkit_plugin}/services/__init__.py +0 -0
  58. {netbox_toolkit → netbox_toolkit_plugin}/services/device_service.py +0 -0
  59. {netbox_toolkit/static/netbox_toolkit → netbox_toolkit_plugin/static/netbox_toolkit_plugin}/css/toolkit.css +0 -0
  60. {netbox_toolkit/static/netbox_toolkit → netbox_toolkit_plugin/static/netbox_toolkit_plugin}/js/toolkit.js +0 -0
  61. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/command_edit.html +0 -0
  62. {netbox_toolkit/templates/netbox_toolkit → netbox_toolkit_plugin/templates/netbox_toolkit_plugin}/commandlog_list.html +0 -0
  63. {netbox_toolkit → netbox_toolkit_plugin}/utils/__init__.py +0 -0
  64. {netbox_toolkit → netbox_toolkit_plugin}/utils/connection.py +0 -0
  65. {netbox_toolkit → netbox_toolkit_plugin}/utils/error_parser.py +0 -0
  66. {netbox_toolkit → netbox_toolkit_plugin}/utils/network.py +0 -0
  67. {netbox_toolkit_plugin-0.1.0.dist-info → netbox_toolkit_plugin-0.1.1.dist-info}/WHEEL +0 -0
  68. {netbox_toolkit_plugin-0.1.0.dist-info → netbox_toolkit_plugin-0.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,108 @@
1
+ # Generated by Django 5.1.4 on 2025-05-23 14:41
2
+
3
+ import django.db.models.deletion
4
+ import taggit.managers
5
+ import utilities.json
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+ initial = True
11
+
12
+ dependencies = [
13
+ ("dcim", "0200_populate_mac_addresses"),
14
+ ("extras", "0122_charfield_null_choices"),
15
+ ]
16
+
17
+ operations = [
18
+ migrations.CreateModel(
19
+ name="Command",
20
+ fields=[
21
+ (
22
+ "id",
23
+ models.BigAutoField(
24
+ auto_created=True, primary_key=True, serialize=False
25
+ ),
26
+ ),
27
+ ("created", models.DateTimeField(auto_now_add=True, null=True)),
28
+ ("last_updated", models.DateTimeField(auto_now=True, null=True)),
29
+ (
30
+ "custom_field_data",
31
+ models.JSONField(
32
+ blank=True,
33
+ default=dict,
34
+ encoder=utilities.json.CustomFieldJSONEncoder,
35
+ ),
36
+ ),
37
+ ("name", models.CharField(max_length=100)),
38
+ ("command", models.TextField()),
39
+ ("description", models.TextField(blank=True)),
40
+ (
41
+ "device_type",
42
+ models.ForeignKey(
43
+ on_delete=django.db.models.deletion.CASCADE,
44
+ related_name="toolkit_commands",
45
+ to="dcim.devicetype",
46
+ ),
47
+ ),
48
+ (
49
+ "tags",
50
+ taggit.managers.TaggableManager(
51
+ through="extras.TaggedItem", to="extras.Tag"
52
+ ),
53
+ ),
54
+ ],
55
+ options={
56
+ "abstract": False,
57
+ },
58
+ ),
59
+ migrations.CreateModel(
60
+ name="CommandLog",
61
+ fields=[
62
+ (
63
+ "id",
64
+ models.BigAutoField(
65
+ auto_created=True, primary_key=True, serialize=False
66
+ ),
67
+ ),
68
+ ("created", models.DateTimeField(auto_now_add=True, null=True)),
69
+ ("last_updated", models.DateTimeField(auto_now=True, null=True)),
70
+ (
71
+ "custom_field_data",
72
+ models.JSONField(
73
+ blank=True,
74
+ default=dict,
75
+ encoder=utilities.json.CustomFieldJSONEncoder,
76
+ ),
77
+ ),
78
+ ("output", models.TextField()),
79
+ ("username", models.CharField(max_length=100)),
80
+ ("execution_time", models.DateTimeField(auto_now_add=True)),
81
+ (
82
+ "command",
83
+ models.ForeignKey(
84
+ on_delete=django.db.models.deletion.CASCADE,
85
+ related_name="logs",
86
+ to="netbox_toolkit_plugin.command",
87
+ ),
88
+ ),
89
+ (
90
+ "device",
91
+ models.ForeignKey(
92
+ on_delete=django.db.models.deletion.CASCADE,
93
+ related_name="command_logs",
94
+ to="dcim.device",
95
+ ),
96
+ ),
97
+ (
98
+ "tags",
99
+ taggit.managers.TaggableManager(
100
+ through="extras.TaggedItem", to="extras.Tag"
101
+ ),
102
+ ),
103
+ ],
104
+ options={
105
+ "abstract": False,
106
+ },
107
+ ),
108
+ ]
@@ -0,0 +1,70 @@
1
+ # Generated by Django 5.1.4 on 2025-05-26 12:11
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("dcim", "0200_populate_mac_addresses"),
10
+ ("netbox_toolkit_plugin", "0001_initial"),
11
+ ]
12
+
13
+ operations = [
14
+ # First remove the old field
15
+ migrations.RemoveField(
16
+ model_name="command",
17
+ name="device_type",
18
+ ),
19
+ # Add all new fields
20
+ migrations.AddField(
21
+ model_name="command",
22
+ name="platform",
23
+ field=models.ForeignKey(
24
+ default=1,
25
+ on_delete=django.db.models.deletion.CASCADE,
26
+ related_name="toolkit_commands",
27
+ to="dcim.platform",
28
+ ),
29
+ preserve_default=False,
30
+ ),
31
+ migrations.AddField(
32
+ model_name="command",
33
+ name="command_type",
34
+ field=models.CharField(default="show", max_length=50),
35
+ ),
36
+ migrations.AddField(
37
+ model_name="command",
38
+ name="requires_config_mode",
39
+ field=models.BooleanField(default=False),
40
+ ),
41
+ migrations.AddField(
42
+ model_name="command",
43
+ name="requires_enable",
44
+ field=models.BooleanField(default=False),
45
+ ),
46
+ migrations.AddField(
47
+ model_name="commandlog",
48
+ name="error_message",
49
+ field=models.TextField(blank=True),
50
+ ),
51
+ migrations.AddField(
52
+ model_name="commandlog",
53
+ name="execution_duration",
54
+ field=models.FloatField(blank=True, null=True),
55
+ ),
56
+ migrations.AddField(
57
+ model_name="commandlog",
58
+ name="success",
59
+ field=models.BooleanField(default=True),
60
+ ),
61
+ # Then alter model options after fields exist
62
+ migrations.AlterModelOptions(
63
+ name="command",
64
+ options={"ordering": ["platform", "name"]},
65
+ ),
66
+ migrations.AlterUniqueTogether(
67
+ name="command",
68
+ unique_together={("platform", "name")},
69
+ ),
70
+ ]
@@ -7,16 +7,22 @@ def migrate_command_types(apps, schema_editor):
7
7
  """
8
8
  Migrate existing diagnostic and troubleshooting commands to 'show' type
9
9
  """
10
- Command = apps.get_model('netbox_toolkit', 'Command')
11
-
10
+ Command = apps.get_model("netbox_toolkit_plugin", "Command")
11
+
12
12
  # Update diagnostic commands to show
13
- diagnostic_count = Command.objects.filter(command_type='diagnostic').update(command_type='show')
14
-
15
- # Update troubleshooting commands to show
16
- troubleshooting_count = Command.objects.filter(command_type='troubleshooting').update(command_type='show')
17
-
13
+ diagnostic_count = Command.objects.filter(command_type="diagnostic").update(
14
+ command_type="show"
15
+ )
16
+
17
+ # Update troubleshooting commands to show
18
+ troubleshooting_count = Command.objects.filter(
19
+ command_type="troubleshooting"
20
+ ).update(command_type="show")
21
+
18
22
  print(f"Migration: Updated {diagnostic_count} diagnostic commands to 'show' type")
19
- print(f"Migration: Updated {troubleshooting_count} troubleshooting commands to 'show' type")
23
+ print(
24
+ f"Migration: Updated {troubleshooting_count} troubleshooting commands to 'show' type"
25
+ )
20
26
 
21
27
 
22
28
  def reverse_migrate_command_types(apps, schema_editor):
@@ -31,15 +37,23 @@ def reverse_migrate_command_types(apps, schema_editor):
31
37
 
32
38
 
33
39
  class Migration(migrations.Migration):
34
-
35
40
  dependencies = [
36
- ('netbox_toolkit', '0002_alter_command_options_alter_command_unique_together_and_more'),
41
+ (
42
+ "netbox_toolkit_plugin",
43
+ "0002_alter_command_options_alter_command_unique_together_and_more",
44
+ ),
37
45
  ]
38
46
 
39
47
  operations = [
40
48
  migrations.AlterModelOptions(
41
- name='command',
42
- options={'ordering': ['platform', 'name'], 'permissions': [('execute_show_command', 'Can execute show commands'), ('execute_config_command', 'Can execute configuration commands')]},
49
+ name="command",
50
+ options={
51
+ "ordering": ["platform", "name"],
52
+ "permissions": [
53
+ ("execute_show_command", "Can execute show commands"),
54
+ ("execute_config_command", "Can execute configuration commands"),
55
+ ],
56
+ },
43
57
  ),
44
58
  migrations.RunPython(
45
59
  migrate_command_types,
@@ -5,68 +5,66 @@ from django.db import migrations
5
5
 
6
6
  def remove_django_permissions(apps, schema_editor):
7
7
  """Remove old Django permissions that are no longer needed"""
8
- Permission = apps.get_model('auth', 'Permission')
9
- ContentType = apps.get_model('contenttypes', 'ContentType')
10
-
8
+ Permission = apps.get_model("auth", "Permission")
9
+ ContentType = apps.get_model("contenttypes", "ContentType")
10
+
11
11
  try:
12
12
  # Get the Command content type
13
- command_ct = ContentType.objects.get(app_label='netbox_toolkit', model='command')
14
-
13
+ command_ct = ContentType.objects.get(
14
+ app_label="netbox_toolkit_plugin", model="command"
15
+ )
16
+
15
17
  # Remove the custom Django permissions
16
- custom_permissions = [
17
- 'execute_show_command',
18
- 'execute_config_command'
19
- ]
20
-
18
+ custom_permissions = ["execute_show_command", "execute_config_command"]
19
+
21
20
  deleted_count = 0
22
21
  for codename in custom_permissions:
23
22
  count, _ = Permission.objects.filter(
24
- content_type=command_ct,
25
- codename=codename
23
+ content_type=command_ct, codename=codename
26
24
  ).delete()
27
25
  deleted_count += count
28
-
26
+
29
27
  print(f"Removed {deleted_count} old Django permissions")
30
-
28
+
31
29
  except ContentType.DoesNotExist:
32
30
  # Command model doesn't exist yet, skip
33
31
  print("Command model not found, skipping permission removal")
34
32
  except Exception as e:
35
33
  print(f"Warning: Could not remove old permissions: {e}")
36
34
 
35
+
37
36
  def restore_django_permissions(apps, schema_editor):
38
37
  """Restore Django permissions if migration is reversed"""
39
- Permission = apps.get_model('auth', 'Permission')
40
- ContentType = apps.get_model('contenttypes', 'ContentType')
41
-
38
+ Permission = apps.get_model("auth", "Permission")
39
+ ContentType = apps.get_model("contenttypes", "ContentType")
40
+
42
41
  try:
43
42
  # Get the Command content type
44
- command_ct = ContentType.objects.get(app_label='netbox_toolkit', model='command')
45
-
43
+ command_ct = ContentType.objects.get(
44
+ app_label="netbox_toolkit_plugin", model="command"
45
+ )
46
+
46
47
  # Recreate the custom Django permissions
47
48
  permissions_to_create = [
48
- ('execute_show_command', 'Can execute show commands'),
49
- ('execute_config_command', 'Can execute configuration commands'),
49
+ ("execute_show_command", "Can execute show commands"),
50
+ ("execute_config_command", "Can execute configuration commands"),
50
51
  ]
51
-
52
+
52
53
  for codename, name in permissions_to_create:
53
54
  Permission.objects.get_or_create(
54
- content_type=command_ct,
55
- codename=codename,
56
- defaults={'name': name}
55
+ content_type=command_ct, codename=codename, defaults={"name": name}
57
56
  )
58
-
57
+
59
58
  print("Restored old Django permissions")
60
-
59
+
61
60
  except ContentType.DoesNotExist:
62
61
  # Command model doesn't exist, skip
63
62
  print("Command model not found, skipping permission restoration")
64
63
 
65
64
 
66
65
  class Migration(migrations.Migration):
67
-
68
66
  dependencies = [
69
- ('netbox_toolkit', '0003_permission_system_update'),
67
+ ("netbox_toolkit_plugin", "0003_permission_system_update"),
70
68
  ]
71
69
 
72
70
  operations = [
@@ -4,22 +4,21 @@ from django.db import migrations
4
4
 
5
5
 
6
6
  class Migration(migrations.Migration):
7
-
8
7
  dependencies = [
9
- ('netbox_toolkit', '0004_remove_django_permissions'),
8
+ ("netbox_toolkit_plugin", "0004_remove_django_permissions"),
10
9
  ]
11
10
 
12
11
  operations = [
13
12
  migrations.AlterModelOptions(
14
- name='command',
15
- options={'ordering': ['platform', 'name']},
13
+ name="command",
14
+ options={"ordering": ["platform", "name"]},
16
15
  ),
17
16
  migrations.RemoveField(
18
- model_name='command',
19
- name='requires_config_mode',
17
+ model_name="command",
18
+ name="requires_config_mode",
20
19
  ),
21
20
  migrations.RemoveField(
22
- model_name='command',
23
- name='requires_enable',
21
+ model_name="command",
22
+ name="requires_enable",
24
23
  ),
25
24
  ]
@@ -4,25 +4,24 @@ from django.db import migrations, models
4
4
 
5
5
 
6
6
  class Migration(migrations.Migration):
7
-
8
7
  dependencies = [
9
- ('netbox_toolkit', '0005_alter_command_options_and_more'),
8
+ ("netbox_toolkit_plugin", "0005_alter_command_options_and_more"),
10
9
  ]
11
10
 
12
11
  operations = [
13
12
  migrations.AddField(
14
- model_name='commandlog',
15
- name='parsed_data',
13
+ model_name="commandlog",
14
+ name="parsed_data",
16
15
  field=models.JSONField(blank=True, null=True),
17
16
  ),
18
17
  migrations.AddField(
19
- model_name='commandlog',
20
- name='parsing_success',
18
+ model_name="commandlog",
19
+ name="parsing_success",
21
20
  field=models.BooleanField(default=False),
22
21
  ),
23
22
  migrations.AddField(
24
- model_name='commandlog',
25
- name='parsing_template',
23
+ model_name="commandlog",
24
+ name="parsing_template",
26
25
  field=models.CharField(blank=True, max_length=255),
27
26
  ),
28
27
  ]
@@ -4,15 +4,17 @@ from django.db import migrations, models
4
4
 
5
5
 
6
6
  class Migration(migrations.Migration):
7
-
8
7
  dependencies = [
9
- ('netbox_toolkit', '0006_commandlog_parsed_data_commandlog_parsing_success_and_more'),
8
+ (
9
+ "netbox_toolkit_plugin",
10
+ "0006_commandlog_parsed_data_commandlog_parsing_success_and_more",
11
+ ),
10
12
  ]
11
13
 
12
14
  operations = [
13
15
  migrations.AlterField(
14
- model_name='commandlog',
15
- name='parsing_template',
16
+ model_name="commandlog",
17
+ name="parsing_template",
16
18
  field=models.CharField(blank=True, max_length=255, null=True),
17
19
  ),
18
20
  ]
@@ -3,87 +3,86 @@ from django.core.exceptions import ValidationError
3
3
  from netbox.models import NetBoxModel
4
4
  from dcim.models import Device
5
5
 
6
+
6
7
  class Command(NetBoxModel):
7
8
  name = models.CharField(max_length=100)
8
9
  command = models.TextField()
9
10
  description = models.TextField(blank=True)
10
-
11
+
11
12
  # Platform-based association (required)
12
13
  platform = models.ForeignKey(
13
- to='dcim.Platform',
14
+ to="dcim.Platform",
14
15
  on_delete=models.CASCADE,
15
- related_name='toolkit_commands',
16
- help_text="Platform this command is designed for (e.g., cisco_ios, cisco_nxos, generic)"
16
+ related_name="toolkit_commands",
17
+ help_text="Platform this command is designed for (e.g., cisco_ios, cisco_nxos, generic)",
17
18
  )
18
-
19
+
19
20
  # Command categorization
20
21
  command_type = models.CharField(
21
22
  max_length=50,
22
23
  choices=[
23
- ('show', 'Show Command'),
24
- ('config', 'Configuration Command'),
24
+ ("show", "Show Command"),
25
+ ("config", "Configuration Command"),
25
26
  ],
26
- default='show',
27
- help_text="Type of command for categorization and permission control"
27
+ default="show",
28
+ help_text="Type of command for categorization and permission control",
28
29
  )
29
30
 
30
31
  class Meta:
31
- ordering = ['platform', 'name']
32
- unique_together = [['platform', 'name']]
32
+ ordering = ["platform", "name"]
33
+ unique_together = [["platform", "name"]]
33
34
 
34
35
  def __str__(self):
35
36
  return f"{self.name} ({self.platform})"
36
-
37
+
37
38
  def get_absolute_url(self):
38
39
  """Return the URL for this object"""
39
40
  from django.urls import reverse
40
- return reverse('plugins:netbox_toolkit:command_detail', kwargs={'pk': self.pk})
41
+
42
+ return reverse(
43
+ "plugins:netbox_toolkit_plugin:command_detail", kwargs={"pk": self.pk}
44
+ )
45
+
41
46
 
42
47
  class CommandLog(NetBoxModel):
43
48
  command = models.ForeignKey(
44
- to=Command,
45
- on_delete=models.CASCADE,
46
- related_name='logs'
49
+ to=Command, on_delete=models.CASCADE, related_name="logs"
47
50
  )
48
51
  device = models.ForeignKey(
49
- to='dcim.Device',
50
- on_delete=models.CASCADE,
51
- related_name='command_logs'
52
+ to="dcim.Device", on_delete=models.CASCADE, related_name="command_logs"
52
53
  )
53
54
  output = models.TextField()
54
55
  username = models.CharField(max_length=100)
55
56
  execution_time = models.DateTimeField(auto_now_add=True)
56
-
57
+
57
58
  # Execution details added in migration
58
59
  success = models.BooleanField(default=True)
59
60
  error_message = models.TextField(blank=True)
60
61
  execution_duration = models.FloatField(
61
- blank=True,
62
- null=True,
63
- help_text="Command execution time in seconds"
62
+ blank=True, null=True, help_text="Command execution time in seconds"
64
63
  )
65
-
64
+
66
65
  # Parsing details for TextFSM
67
66
  parsed_data = models.JSONField(
68
- blank=True,
69
- null=True,
70
- help_text="Parsed structured data from command output"
67
+ blank=True, null=True, help_text="Parsed structured data from command output"
71
68
  )
72
69
  parsing_success = models.BooleanField(
73
- default=False,
74
- help_text="Whether the output was successfully parsed"
70
+ default=False, help_text="Whether the output was successfully parsed"
75
71
  )
76
72
  parsing_template = models.CharField(
77
73
  max_length=255,
78
74
  blank=True,
79
75
  null=True,
80
- help_text="Name of the TextFSM template used for parsing"
76
+ help_text="Name of the TextFSM template used for parsing",
81
77
  )
82
78
 
83
79
  def __str__(self):
84
80
  return f"{self.command} on {self.device}"
85
-
81
+
86
82
  def get_absolute_url(self):
87
83
  """Return the URL for this object"""
88
84
  from django.urls import reverse
89
- return reverse('plugins:netbox_toolkit:commandlog_view', kwargs={'pk': self.pk})
85
+
86
+ return reverse(
87
+ "plugins:netbox_toolkit_plugin:commandlog_view", kwargs={"pk": self.pk}
88
+ )
@@ -9,22 +9,22 @@ menu = PluginMenu(
9
9
  "Commands",
10
10
  (
11
11
  PluginMenuItem(
12
- link="plugins:netbox_toolkit:command_list",
12
+ link="plugins:netbox_toolkit_plugin:command_list",
13
13
  link_text="Commands",
14
14
  buttons=(
15
15
  PluginMenuButton(
16
- "plugins:netbox_toolkit:command_add",
16
+ "plugins:netbox_toolkit_plugin:command_add",
17
17
  "Add",
18
18
  "mdi mdi-plus-thick",
19
- ButtonColorChoices.GRAY
19
+ ButtonColorChoices.GRAY,
20
20
  ),
21
- )
21
+ ),
22
22
  ),
23
23
  PluginMenuItem(
24
- link="plugins:netbox_toolkit:commandlog_list",
24
+ link="plugins:netbox_toolkit_plugin:commandlog_list",
25
25
  link_text="Command Logs",
26
26
  ),
27
27
  ),
28
28
  ),
29
29
  ),
30
- )
30
+ )