netbox-toolkit-plugin 0.1.1__tar.gz → 0.1.3__tar.gz
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.
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/PKG-INFO +2 -2
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/README.md +1 -1
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/__init__.py +1 -1
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/admin.py +20 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/mixins.py +20 -16
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/schemas.py +53 -74
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/serializers.py +10 -11
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/urls.py +2 -1
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/views/__init__.py +4 -3
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/views/command_logs.py +80 -73
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/views/commands.py +140 -134
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/connectors/__init__.py +15 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/connectors/base.py +30 -31
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/connectors/factory.py +22 -26
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/connectors/netmiko_connector.py +18 -28
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/connectors/scrapli_connector.py +17 -16
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/exceptions.py +0 -7
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/filtersets.py +69 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/forms.py +13 -11
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/migrations/0008_remove_parsed_data_storage.py +26 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/models.py +2 -17
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/navigation.py +3 -0
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/search.py +24 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/services/__init__.py +1 -1
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/services/command_service.py +7 -10
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/services/device_service.py +40 -32
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/services/rate_limiting_service.py +4 -3
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/config.py → netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/settings.py +17 -7
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/static/netbox_toolkit_plugin/js/toolkit.js +245 -119
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/tables.py +10 -1
- netbox_toolkit_plugin-0.1.3/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/commandlog.html +102 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/device_toolkit.html +37 -33
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/urls.py +10 -3
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/utils/connection.py +54 -54
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/utils/error_parser.py +128 -109
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/utils/logging.py +1 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/utils/network.py +74 -47
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/views.py +51 -22
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/PKG-INFO +2 -2
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/SOURCES.txt +2 -1
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/pyproject.toml +2 -2
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/admin.py +0 -16
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/connectors/__init__.py +0 -15
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/filtersets.py +0 -85
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/search.py +0 -21
- netbox_toolkit_plugin-0.1.1/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/commandlog.html +0 -170
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/LICENSE +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/__init__.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0001_initial.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0002_alter_command_options_alter_command_unique_together_and_more.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0003_permission_system_update.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0004_remove_django_permissions.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0005_alter_command_options_and_more.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0006_commandlog_parsed_data_commandlog_parsing_success_and_more.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/0007_alter_commandlog_parsing_template.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/migrations/__init__.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/static/netbox_toolkit_plugin/css/toolkit.css +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit/command.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit/command_list.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit/commandlog.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit/device_toolkit.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/command.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/command_edit.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/command_list.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/templates/netbox_toolkit_plugin/commandlog_list.html +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/utils/__init__.py +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/dependency_links.txt +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/entry_points.txt +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/requires.txt +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin.egg-info/top_level.txt +0 -0
- {netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: netbox-toolkit-plugin
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: NetBox plugin for running pre-defined commands on network devices
|
5
5
|
Author: Andy Norwood
|
6
6
|
Classifier: Development Status :: 3 - Alpha
|
@@ -67,7 +67,7 @@ A NetBox plugin that allows you to run commands on network devices directly from
|
|
67
67
|
|
68
68
|
## Contributing
|
69
69
|
|
70
|
-
**🚀 Want to Contribute?** Start with the [Contributor Guide](./docs/contributing.md) for a fast overview of the codebase.
|
70
|
+
**🚀 Want to Contribute?** Start with the [Contributor Guide](./docs/development/contributing.md) for a fast overview of the codebase.
|
71
71
|
|
72
72
|
|
73
73
|
## Future ideas:
|
@@ -46,7 +46,7 @@ A NetBox plugin that allows you to run commands on network devices directly from
|
|
46
46
|
|
47
47
|
## Contributing
|
48
48
|
|
49
|
-
**🚀 Want to Contribute?** Start with the [Contributor Guide](./docs/contributing.md) for a fast overview of the codebase.
|
49
|
+
**🚀 Want to Contribute?** Start with the [Contributor Guide](./docs/development/contributing.md) for a fast overview of the codebase.
|
50
50
|
|
51
51
|
|
52
52
|
## Future ideas:
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from django.contrib import admin
|
2
|
+
|
3
|
+
from netbox.admin import NetBoxModelAdmin
|
4
|
+
|
5
|
+
from .models import Command, CommandLog
|
6
|
+
|
7
|
+
|
8
|
+
@admin.register(Command)
|
9
|
+
class CommandAdmin(NetBoxModelAdmin):
|
10
|
+
list_display = ("name", "platform", "command_type", "description")
|
11
|
+
list_filter = ("platform", "command_type")
|
12
|
+
search_fields = ("name", "command", "description")
|
13
|
+
|
14
|
+
|
15
|
+
@admin.register(CommandLog)
|
16
|
+
class CommandLogAdmin(NetBoxModelAdmin):
|
17
|
+
list_display = ("command", "device", "username", "execution_time")
|
18
|
+
list_filter = ("command", "device", "username", "execution_time")
|
19
|
+
search_fields = ("command__name", "device__name", "username", "output")
|
20
|
+
readonly_fields = ("output", "execution_time")
|
{netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/mixins.py
RENAMED
@@ -1,54 +1,58 @@
|
|
1
1
|
"""
|
2
2
|
Common mixins and utilities for NetBox Toolkit API views
|
3
3
|
"""
|
4
|
-
|
4
|
+
|
5
5
|
from django.contrib.contenttypes.models import ContentType
|
6
|
+
|
6
7
|
from users.models import ObjectPermission
|
7
8
|
|
8
9
|
|
9
10
|
class APIResponseMixin:
|
10
11
|
"""Mixin to add consistent API response headers"""
|
11
|
-
|
12
|
+
|
12
13
|
def finalize_response(self, request, response, *args, **kwargs):
|
13
14
|
"""Add custom headers to all responses"""
|
14
15
|
response = super().finalize_response(request, response, *args, **kwargs)
|
15
|
-
|
16
|
+
|
16
17
|
# Add API version header
|
17
|
-
response[
|
18
|
-
|
18
|
+
response["X-NetBox-Toolkit-API-Version"] = "1.0"
|
19
|
+
|
19
20
|
return response
|
20
21
|
|
21
22
|
|
22
23
|
class PermissionCheckMixin:
|
23
24
|
"""Mixin for NetBox ObjectPermission checking"""
|
24
|
-
|
25
|
+
|
25
26
|
def _user_has_action_permission(self, user, obj, action):
|
26
27
|
"""Check if user has permission for a specific action on an object using NetBox's ObjectPermission system"""
|
27
28
|
# Get content type for the object
|
28
29
|
content_type = ContentType.objects.get_for_model(obj)
|
29
|
-
|
30
|
+
|
30
31
|
# Check if user has any ObjectPermissions with the required action
|
31
32
|
user_permissions = ObjectPermission.objects.filter(
|
32
|
-
object_types__in=[content_type],
|
33
|
-
actions__contains=[action],
|
34
|
-
enabled=True
|
33
|
+
object_types__in=[content_type], actions__contains=[action], enabled=True
|
35
34
|
)
|
36
|
-
|
35
|
+
|
37
36
|
# Check if user is assigned to any groups with this permission
|
38
37
|
user_groups = user.groups.all()
|
39
38
|
for permission in user_permissions:
|
40
39
|
# Check if permission applies to user or user's groups
|
41
|
-
if (
|
42
|
-
permission.
|
43
|
-
|
40
|
+
if (
|
41
|
+
permission.users.filter(id=user.id).exists()
|
42
|
+
or permission.groups.filter(
|
43
|
+
id__in=user_groups.values_list("id", flat=True)
|
44
|
+
).exists()
|
45
|
+
):
|
44
46
|
# If there are constraints, evaluate them
|
45
47
|
if permission.constraints:
|
46
48
|
# Create a queryset with the constraints and check if the object matches
|
47
|
-
queryset = content_type.model_class().objects.filter(
|
49
|
+
queryset = content_type.model_class().objects.filter(
|
50
|
+
**permission.constraints
|
51
|
+
)
|
48
52
|
if queryset.filter(id=obj.id).exists():
|
49
53
|
return True
|
50
54
|
else:
|
51
55
|
# No constraints means permission applies to all objects of this type
|
52
56
|
return True
|
53
|
-
|
57
|
+
|
54
58
|
return False
|
{netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/schemas.py
RENAMED
@@ -1,44 +1,40 @@
|
|
1
1
|
"""
|
2
2
|
OpenAPI schema definitions for NetBox Toolkit API
|
3
3
|
"""
|
4
|
-
from drf_spectacular.utils import extend_schema, OpenApiResponse
|
5
4
|
|
5
|
+
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
6
6
|
|
7
7
|
# Command ViewSet Schemas
|
8
8
|
COMMAND_LIST_SCHEMA = extend_schema(
|
9
9
|
summary="List commands",
|
10
10
|
description="Retrieve a list of all commands available in the system.",
|
11
|
-
tags=["Commands"]
|
11
|
+
tags=["Commands"],
|
12
12
|
)
|
13
13
|
|
14
14
|
COMMAND_RETRIEVE_SCHEMA = extend_schema(
|
15
15
|
summary="Retrieve command",
|
16
16
|
description="Retrieve details of a specific command.",
|
17
|
-
tags=["Commands"]
|
17
|
+
tags=["Commands"],
|
18
18
|
)
|
19
19
|
|
20
20
|
COMMAND_CREATE_SCHEMA = extend_schema(
|
21
|
-
summary="Create command",
|
22
|
-
description="Create a new command.",
|
23
|
-
tags=["Commands"]
|
21
|
+
summary="Create command", description="Create a new command.", tags=["Commands"]
|
24
22
|
)
|
25
23
|
|
26
24
|
COMMAND_UPDATE_SCHEMA = extend_schema(
|
27
25
|
summary="Update command",
|
28
26
|
description="Update an existing command.",
|
29
|
-
tags=["Commands"]
|
27
|
+
tags=["Commands"],
|
30
28
|
)
|
31
29
|
|
32
30
|
COMMAND_PARTIAL_UPDATE_SCHEMA = extend_schema(
|
33
31
|
summary="Partial update command",
|
34
32
|
description="Partially update an existing command.",
|
35
|
-
tags=["Commands"]
|
33
|
+
tags=["Commands"],
|
36
34
|
)
|
37
35
|
|
38
36
|
COMMAND_DESTROY_SCHEMA = extend_schema(
|
39
|
-
summary="Delete command",
|
40
|
-
description="Delete a command.",
|
41
|
-
tags=["Commands"]
|
37
|
+
summary="Delete command", description="Delete a command.", tags=["Commands"]
|
42
38
|
)
|
43
39
|
|
44
40
|
COMMAND_EXECUTE_SCHEMA = extend_schema(
|
@@ -57,36 +53,25 @@ COMMAND_EXECUTE_SCHEMA = extend_schema(
|
|
57
53
|
"command": {
|
58
54
|
"id": 1,
|
59
55
|
"name": "show interfaces",
|
60
|
-
"command_type": "show"
|
61
|
-
},
|
62
|
-
"device": {
|
63
|
-
"id": 1,
|
64
|
-
"name": "switch01.example.com"
|
65
|
-
},
|
66
|
-
"syntax_error": {
|
67
|
-
"detected": False
|
56
|
+
"command_type": "show",
|
68
57
|
},
|
58
|
+
"device": {"id": 1, "name": "switch01.example.com"},
|
59
|
+
"syntax_error": {"detected": False},
|
69
60
|
"parsed_output": {
|
70
61
|
"success": True,
|
71
62
|
"method": "textfsm",
|
72
|
-
"data": [{"interface": "GigabitEthernet1/0/1", "status": "up"}]
|
73
|
-
}
|
63
|
+
"data": [{"interface": "GigabitEthernet1/0/1", "status": "up"}],
|
64
|
+
},
|
74
65
|
}
|
75
|
-
]
|
66
|
+
],
|
76
67
|
),
|
77
68
|
400: OpenApiResponse(
|
78
69
|
description="Bad request - validation errors or command execution failed"
|
79
70
|
),
|
80
|
-
403: OpenApiResponse(
|
81
|
-
|
82
|
-
),
|
83
|
-
|
84
|
-
description="Not found - command or device not found"
|
85
|
-
),
|
86
|
-
429: OpenApiResponse(
|
87
|
-
description="Too many requests - rate limit exceeded"
|
88
|
-
)
|
89
|
-
}
|
71
|
+
403: OpenApiResponse(description="Forbidden - insufficient permissions"),
|
72
|
+
404: OpenApiResponse(description="Not found - command or device not found"),
|
73
|
+
429: OpenApiResponse(description="Too many requests - rate limit exceeded"),
|
74
|
+
},
|
90
75
|
)
|
91
76
|
|
92
77
|
COMMAND_BULK_EXECUTE_SCHEMA = extend_schema(
|
@@ -104,13 +89,13 @@ COMMAND_BULK_EXECUTE_SCHEMA = extend_schema(
|
|
104
89
|
"command_id": {"type": "integer"},
|
105
90
|
"device_id": {"type": "integer"},
|
106
91
|
"username": {"type": "string"},
|
107
|
-
"password": {"type": "string", "format": "password"}
|
92
|
+
"password": {"type": "string", "format": "password"},
|
108
93
|
},
|
109
|
-
"required": ["command_id", "device_id", "username", "password"]
|
110
|
-
}
|
94
|
+
"required": ["command_id", "device_id", "username", "password"],
|
95
|
+
},
|
111
96
|
}
|
112
97
|
},
|
113
|
-
"required": ["executions"]
|
98
|
+
"required": ["executions"],
|
114
99
|
},
|
115
100
|
responses={
|
116
101
|
200: OpenApiResponse(
|
@@ -119,54 +104,54 @@ COMMAND_BULK_EXECUTE_SCHEMA = extend_schema(
|
|
119
104
|
{
|
120
105
|
"results": [
|
121
106
|
{"execution_id": 1, "success": True, "command_log_id": 123},
|
122
|
-
{
|
107
|
+
{
|
108
|
+
"execution_id": 2,
|
109
|
+
"success": False,
|
110
|
+
"error": "Permission denied",
|
111
|
+
},
|
123
112
|
],
|
124
|
-
"summary": {
|
125
|
-
"total": 2,
|
126
|
-
"successful": 1,
|
127
|
-
"failed": 1
|
128
|
-
}
|
113
|
+
"summary": {"total": 2, "successful": 1, "failed": 1},
|
129
114
|
}
|
130
|
-
]
|
115
|
+
],
|
131
116
|
)
|
132
|
-
}
|
117
|
+
},
|
133
118
|
)
|
134
119
|
|
135
120
|
# Command Log ViewSet Schemas
|
136
121
|
COMMAND_LOG_LIST_SCHEMA = extend_schema(
|
137
122
|
summary="List command logs",
|
138
123
|
description="Retrieve a list of command execution logs with filtering and search capabilities.",
|
139
|
-
tags=["Command Logs"]
|
124
|
+
tags=["Command Logs"],
|
140
125
|
)
|
141
126
|
|
142
127
|
COMMAND_LOG_RETRIEVE_SCHEMA = extend_schema(
|
143
128
|
summary="Retrieve command log",
|
144
129
|
description="Retrieve details of a specific command execution log.",
|
145
|
-
tags=["Command Logs"]
|
130
|
+
tags=["Command Logs"],
|
146
131
|
)
|
147
132
|
|
148
133
|
COMMAND_LOG_CREATE_SCHEMA = extend_schema(
|
149
134
|
summary="Create command log",
|
150
135
|
description="Create a new command execution log entry.",
|
151
|
-
tags=["Command Logs"]
|
136
|
+
tags=["Command Logs"],
|
152
137
|
)
|
153
138
|
|
154
139
|
COMMAND_LOG_UPDATE_SCHEMA = extend_schema(
|
155
140
|
summary="Update command log",
|
156
141
|
description="Update an existing command log entry.",
|
157
|
-
tags=["Command Logs"]
|
142
|
+
tags=["Command Logs"],
|
158
143
|
)
|
159
144
|
|
160
145
|
COMMAND_LOG_PARTIAL_UPDATE_SCHEMA = extend_schema(
|
161
146
|
summary="Partial update command log",
|
162
147
|
description="Partially update an existing command log entry.",
|
163
|
-
tags=["Command Logs"]
|
148
|
+
tags=["Command Logs"],
|
164
149
|
)
|
165
150
|
|
166
151
|
COMMAND_LOG_DESTROY_SCHEMA = extend_schema(
|
167
152
|
summary="Delete command log",
|
168
153
|
description="Delete a command log entry.",
|
169
|
-
tags=["Command Logs"]
|
154
|
+
tags=["Command Logs"],
|
170
155
|
)
|
171
156
|
|
172
157
|
COMMAND_LOG_STATISTICS_SCHEMA = extend_schema(
|
@@ -180,55 +165,49 @@ COMMAND_LOG_STATISTICS_SCHEMA = extend_schema(
|
|
180
165
|
{
|
181
166
|
"total_logs": 1000,
|
182
167
|
"success_rate": 85.5,
|
183
|
-
"last_24h": {
|
184
|
-
"total": 50,
|
185
|
-
"successful": 45,
|
186
|
-
"failed": 5
|
187
|
-
},
|
168
|
+
"last_24h": {"total": 50, "successful": 45, "failed": 5},
|
188
169
|
"top_commands": [
|
189
170
|
{"command_name": "show interfaces", "count": 150},
|
190
|
-
{"command_name": "show version", "count": 120}
|
171
|
+
{"command_name": "show version", "count": 120},
|
191
172
|
],
|
192
173
|
"common_errors": [
|
193
174
|
{"error": "Connection timeout", "count": 10},
|
194
|
-
{"error": "Invalid command", "count": 5}
|
195
|
-
]
|
175
|
+
{"error": "Invalid command", "count": 5},
|
176
|
+
],
|
196
177
|
}
|
197
|
-
]
|
178
|
+
],
|
198
179
|
)
|
199
|
-
}
|
180
|
+
},
|
200
181
|
)
|
201
182
|
|
202
|
-
from drf_spectacular.utils import OpenApiParameter
|
203
|
-
|
204
183
|
COMMAND_LOG_EXPORT_SCHEMA = extend_schema(
|
205
184
|
summary="Export command logs",
|
206
185
|
description="Export command logs in various formats (CSV, JSON).",
|
207
186
|
tags=["Command Logs"],
|
208
187
|
parameters=[
|
209
188
|
OpenApiParameter(
|
210
|
-
name=
|
211
|
-
description=
|
189
|
+
name="format",
|
190
|
+
description="Export format",
|
212
191
|
required=False,
|
213
192
|
type=str,
|
214
|
-
enum=[
|
215
|
-
default=
|
193
|
+
enum=["csv", "json"],
|
194
|
+
default="json",
|
216
195
|
),
|
217
196
|
OpenApiParameter(
|
218
|
-
name=
|
219
|
-
description=
|
197
|
+
name="start_date",
|
198
|
+
description="Start date for export (YYYY-MM-DD)",
|
220
199
|
required=False,
|
221
|
-
type=str
|
200
|
+
type=str,
|
222
201
|
),
|
223
202
|
OpenApiParameter(
|
224
|
-
name=
|
225
|
-
description=
|
203
|
+
name="end_date",
|
204
|
+
description="End date for export (YYYY-MM-DD)",
|
226
205
|
required=False,
|
227
|
-
type=str
|
206
|
+
type=str,
|
228
207
|
),
|
229
208
|
],
|
230
209
|
responses={
|
231
210
|
200: OpenApiResponse(description="Export data"),
|
232
|
-
400: OpenApiResponse(description="Invalid parameters")
|
233
|
-
}
|
211
|
+
400: OpenApiResponse(description="Invalid parameters"),
|
212
|
+
},
|
234
213
|
)
|
{netbox_toolkit_plugin-0.1.1 → netbox_toolkit_plugin-0.1.3}/netbox_toolkit_plugin/api/serializers.py
RENAMED
@@ -1,6 +1,8 @@
|
|
1
|
-
from
|
1
|
+
from dcim.api.serializers import DeviceSerializer, PlatformSerializer
|
2
2
|
from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
|
3
|
-
|
3
|
+
|
4
|
+
from rest_framework import serializers
|
5
|
+
|
4
6
|
from ..models import Command, CommandLog
|
5
7
|
|
6
8
|
|
@@ -44,8 +46,8 @@ class CommandExecutionSerializer(serializers.Serializer):
|
|
44
46
|
"Device must have a primary IP address for command execution"
|
45
47
|
)
|
46
48
|
return value
|
47
|
-
except Device.DoesNotExist:
|
48
|
-
raise serializers.ValidationError("Device not found")
|
49
|
+
except Device.DoesNotExist as e:
|
50
|
+
raise serializers.ValidationError("Device not found") from e
|
49
51
|
|
50
52
|
def validate(self, data):
|
51
53
|
"""Cross-field validation and object retrieval"""
|
@@ -130,9 +132,6 @@ class CommandLogSerializer(NetBoxModelSerializer):
|
|
130
132
|
"success",
|
131
133
|
"error_message",
|
132
134
|
"execution_duration",
|
133
|
-
"parsed_data",
|
134
|
-
"parsing_success",
|
135
|
-
"parsing_template",
|
136
135
|
"created",
|
137
136
|
"last_updated",
|
138
137
|
)
|
@@ -176,8 +175,8 @@ class BulkCommandExecutionSerializer(serializers.Serializer):
|
|
176
175
|
try:
|
177
176
|
Command.objects.get(id=value)
|
178
177
|
return value
|
179
|
-
except Command.DoesNotExist:
|
180
|
-
raise serializers.ValidationError("Command not found")
|
178
|
+
except Command.DoesNotExist as e:
|
179
|
+
raise serializers.ValidationError("Command not found") from e
|
181
180
|
|
182
181
|
def validate_device_id(self, value):
|
183
182
|
"""Validate that the device exists"""
|
@@ -190,5 +189,5 @@ class BulkCommandExecutionSerializer(serializers.Serializer):
|
|
190
189
|
"Device must have a platform assigned"
|
191
190
|
)
|
192
191
|
return value
|
193
|
-
except Device.DoesNotExist:
|
194
|
-
raise serializers.ValidationError("Device not found")
|
192
|
+
except Device.DoesNotExist as e:
|
193
|
+
raise serializers.ValidationError("Device not found") from e
|
@@ -1,10 +1,11 @@
|
|
1
1
|
"""
|
2
2
|
Import all viewsets for easier access
|
3
3
|
"""
|
4
|
-
|
4
|
+
|
5
5
|
from .command_logs import CommandLogViewSet
|
6
|
+
from .commands import CommandViewSet
|
6
7
|
|
7
8
|
__all__ = [
|
8
|
-
|
9
|
-
|
9
|
+
"CommandViewSet",
|
10
|
+
"CommandLogViewSet",
|
10
11
|
]
|