@@ -172,6 +172,129 @@ class Plugins {
172172 } ) ; // loadSession
173173 }
174174
175+ api_test_monitor_plugin ( args , callback ) {
176+ // test existing monitor plugin
177+ var self = this ;
178+ var params = args . params ;
179+ if ( ! this . requireMaster ( args , callback ) ) return ;
180+
181+ if ( ! this . requireParams ( params , {
182+ id : / ^ \w + $ / ,
183+ server : / ^ \w + $ /
184+ } , callback ) ) return ;
185+
186+ this . loadSession ( args , function ( err , session , user ) {
187+ if ( err ) return self . doError ( 'session' , err . message , callback ) ;
188+ if ( ! self . requireValidUser ( session , user , callback ) ) return ;
189+ if ( ! self . requirePrivilege ( user , 'edit_plugins' , callback ) ) return ;
190+
191+ args . user = user ;
192+ args . session = session ;
193+
194+ var plugin = Tools . findObject ( self . plugins , { id : params . id , type : 'monitor' } ) ;
195+ if ( ! plugin ) return self . doError ( 'api' , "Monitor Plugin not found: " + params . id , callback ) ;
196+
197+ var server = self . servers [ params . server ] ;
198+ if ( ! server ) return self . doError ( 'api' , "Server not found: " + params . server , callback ) ;
199+
200+ if ( ! server . info . features || ! server . info . features . testMonitorPlugin ) {
201+ return self . doError ( 'api' , "Server does not support testing monitor plugins (please upgrade xySat)" , callback ) ;
202+ }
203+
204+ self . logDebug ( 5 , "Testing remote monitor plugin" , params ) ;
205+
206+ args . _xy_remote_timer = setTimeout ( function ( ) {
207+ if ( ! callback ) return ; // sanity
208+ callback ( { code : 0 , result : "Error: Remote plugin test has timed out (10 seconds)." } ) ;
209+ callback = null ;
210+ delete args . _xy_remote_timer ;
211+ delete args . _xy_finish ;
212+ } , 10 * 1000 ) ;
213+
214+ args . _xy_finish = function ( data ) {
215+ // called by handleMonitorPluginTestResult in comm.js
216+ if ( ! callback ) return ; // sanity
217+ if ( args . _xy_remote_timer ) {
218+ clearTimeout ( args . _xy_remote_timer ) ;
219+ delete args . _xy_remote_timer ;
220+ }
221+ callback ( { code : 0 , ...data } ) ;
222+ callback = null ;
223+ delete args . _xy_finish ;
224+ } ;
225+
226+ self . doServerBroadcast ( server . id , 'testMonitorPlugin' , { plugin_id : plugin . id , request_id : args . id } ) ;
227+ } ) ; // loadSession
228+ }
229+
230+ api_test_scheduler_plugin ( args , callback ) {
231+ // test existing scheduler plugin
232+ var self = this ;
233+ var params = args . params ;
234+ if ( ! this . requireMaster ( args , callback ) ) return ;
235+
236+ if ( ! this . requireParams ( params , {
237+ id : / ^ \w + $ /
238+ } , callback ) ) return ;
239+
240+ this . loadSession ( args , function ( err , session , user ) {
241+ if ( err ) return self . doError ( 'session' , err . message , callback ) ;
242+ if ( ! self . requireValidUser ( session , user , callback ) ) return ;
243+ if ( ! self . requirePrivilege ( user , 'edit_plugins' , callback ) ) return ;
244+
245+ args . user = user ;
246+ args . session = session ;
247+
248+ var plugin = Tools . findObject ( self . plugins , { id : params . id , type : 'scheduler' } ) ;
249+ if ( ! plugin ) return self . doError ( 'api' , "Scheduler Plugin not found: " + params . id , callback ) ;
250+
251+ self . logDebug ( 5 , "Testing scheduler plugin" , params ) ;
252+
253+ // prep timezone and time stuff
254+ var now = Tools . normalizeTime ( params . epoch || Tools . timeNow ( true ) , { sec : 0 } ) ;
255+ var date = new Date ( now * 1000 ) ;
256+ var tz = params . timezone || self . config . get ( 'tz' ) || Intl . DateTimeFormat ( ) . resolvedOptions ( ) . timeZone ;
257+ var days = { Sunday : 0 , Monday : 1 , Tuesday : 2 , Wednesday : 3 , Thursday : 4 , Friday : 5 , Saturday : 6 } ;
258+ var formatter = new Intl . DateTimeFormat ( 'en-US' ,
259+ { year : 'numeric' , month : '2-digit' , day : 'numeric' , weekday : 'long' , hour : 'numeric' , minute : '2-digit' , hourCycle : 'h23' , timeZone : tz }
260+ ) ;
261+
262+ var tzargs = { } ;
263+ formatter . formatToParts ( date ) . forEach ( function ( part ) {
264+ if ( part . type == 'literal' ) return ;
265+ if ( part . type == 'weekday' ) tzargs [ part . type ] = days [ part . value ] ;
266+ else tzargs [ part . type ] = parseInt ( part . value ) ;
267+ } ) ;
268+
269+ // include reverse-month-day (rday): -1 is last day of month, -2 is 2nd-to-last day, etc.
270+ tzargs . rday = ( tzargs . day - self . getLastDayInMonth ( tzargs . year , tzargs . month ) ) - 1 ;
271+
272+ // items: [{ plugin_id, params, timezone, dargs, now, job }]
273+ var items = [
274+ {
275+ plugin_id : plugin . id ,
276+ params : params . params || { } ,
277+ timezone : tz ,
278+ dargs : tzargs ,
279+ now : now ,
280+ job : {
281+ id : "1234567890" ,
282+ label : "Test"
283+ }
284+ }
285+ ] ;
286+
287+ self . execSchedulerPlugin ( plugin , items , false , function ( resp ) {
288+ // massage results for test API
289+ // resp: { code, description? data?, stdout?, stderr?, child_cmd? }
290+ if ( resp . code ) resp . err = true ;
291+ resp . code = 0 ;
292+ callback ( resp ) ;
293+ } ) ;
294+
295+ } ) ; // loadSession
296+ }
297+
175298 api_delete_plugin ( args , callback ) {
176299 // delete existing plugin
177300 var self = this ;
0 commit comments