1
+ import io
1
2
import json
2
3
import uuid
3
4
7
8
from django .contrib .contenttypes .models import ContentType
8
9
from django .http import HttpResponse
9
10
from django .shortcuts import redirect , render
11
+ from django .utils .safestring import mark_safe
10
12
from django .views .generic import View
11
13
from extras .filtersets import ObjectChangeFilterSet
12
14
from extras .models import ObjectChange
20
22
from .choices import ScriptExecutionStatusChoices
21
23
from .models import ScriptExecution
22
24
from .scripts import run_script
25
+ from .templatetags .scriptmanager import format_exception
23
26
24
27
plugin_config = settings .PLUGINS_CONFIG .get ("netbox_script_manager" )
25
28
@@ -129,7 +132,7 @@ def get_required_permission(self):
129
132
def get (self , request ):
130
133
scripts_found = False
131
134
132
- scripts = util .load_scripts ()
135
+ scripts , failed_modules = util .load_scripts ()
133
136
script_instances = {script_instance .script_path : script_instance for script_instance in models .ScriptInstance .objects .all ()}
134
137
135
138
for script_path , script in scripts .items ():
@@ -153,12 +156,45 @@ def get(self, request):
153
156
154
157
messages .success (request , f'Script "{ script_name } " loaded' )
155
158
159
+ for module_name , exception in failed_modules .items ():
160
+ # This is hackish but it works. Toast messages are kinda limited in netbox.
161
+ messages .error (
162
+ request ,
163
+ mark_safe (
164
+ f'Failed to load module { module_name } : <pre style="overflow-x: scroll; width: 350px;">{ format_exception (exception )} </pre>'
165
+ ),
166
+ )
167
+
156
168
if not scripts_found :
157
169
messages .info (request , "No new scripts found" )
158
170
159
171
return redirect ("plugins:netbox_script_manager:scriptinstance_list" )
160
172
161
173
174
+ class ScriptInstanceSyncView (ContentTypePermissionRequiredMixin , View ):
175
+ def get_required_permission (self ):
176
+ return "netbox_script_manager.sync_scriptinstance"
177
+
178
+ def get (self , request ):
179
+ try :
180
+ from dulwich import porcelain
181
+ except ImportError :
182
+ messages .error (request , "Dulwich is not installed" )
183
+ return redirect ("plugins:netbox_script_manager:scriptinstance_list" )
184
+
185
+ script_root = plugin_config .get ("SCRIPT_ROOT" )
186
+
187
+ output_io = io .StringIO ()
188
+ output = porcelain .pull (script_root , outstream = output_io )
189
+ message = [f"Pulled git repository: { script_root } { output_io .getvalue ()} " ]
190
+
191
+ if output_io :
192
+ message .append (output_io .getvalue ())
193
+
194
+ messages .info (request , "\n " .join (message ))
195
+ return redirect ("plugins:netbox_script_manager:scriptinstance_list" )
196
+
197
+
162
198
@register_model_view (models .ScriptInstance , "execution" )
163
199
class ScriptInstanceScriptExecutionsView (generic .ObjectChildrenView ):
164
200
queryset = models .ScriptInstance .objects .all ()
0 commit comments