2929from intelmq .lib .datatypes import ReturnType , MESSAGES , LogLevel
3030from intelmq .lib .processmanager import *
3131from intelmq .lib .pipeline import PipelineFactory
32+ from intelmq .lib .cli import get_parser , run_handler
3233import intelmq .lib .upgrades as upgrades
3334
35+ from mininterface import run as mrun
36+
3437yaml = YAML (typ = "safe" , pure = True )
3538
3639try :
@@ -213,167 +216,9 @@ def __init__(self, interactive: bool = False, returntype: ReturnType = ReturnTyp
213216 self .abort ('Invalid process manager given: %r, should be one of %r.' '' % (self ._processmanagertype , list (process_managers ().keys ())))
214217
215218 if self ._interactive :
216- parser = argparse .ArgumentParser (
217- prog = APPNAME ,
218- description = DESCRIPTION ,
219- epilog = EPILOG ,
220- formatter_class = argparse .RawDescriptionHelpFormatter ,
221- )
222-
223- parser .add_argument ('--version' , '-v' , action = 'version' , version = VERSION )
224- parser .add_argument ('--type' , '-t' , choices = [i .name .lower () for i in ReturnType ], default = 'text' , help = 'choose if it should return regular text or other machine-readable' )
225- parser .add_argument ('--quiet' , '-q' , action = 'store_true' , help = 'Quiet mode, useful for reloads initiated scripts like logrotate' )
226-
227- subparsers = parser .add_subparsers (title = 'subcommands' )
228-
229- parser_list = subparsers .add_parser ('list' , help = 'Listing bots or queues' )
230- parser_list .add_argument ('kind' , choices = ['bots' , 'queues' , 'queues-and-status' ])
231- parser_list .add_argument ('--non-zero' , '--quiet' , '-q' , action = 'store_true' ,
232- help = 'Only list non-empty queues '
233- 'or the IDs of enabled bots.' )
234- parser_list .add_argument ('--count' , '--sum' , '-s' , action = 'store_true' ,
235- help = 'Only show the total '
236- 'number of messages in queues. '
237- 'Only valid for listing queues.' )
238- parser_list .add_argument ('--configured' , '-c' , action = 'store_true' ,
239- help = 'Only show configured bots' )
240- parser_list .set_defaults (func = self .list )
241-
242- parser_clear = subparsers .add_parser ('clear' , help = 'Clear a queue' )
243- parser_clear .add_argument ('queue' , help = 'queue name' )
244- parser_clear .set_defaults (func = self .clear_queue )
245-
246- parser_log = subparsers .add_parser ('log' , help = 'Get last log lines of a bot' )
247- parser_log .add_argument ('bot_id' , help = 'bot id' , choices = self ._configured_bots_list ())
248- parser_log .add_argument ('number_of_lines' , help = 'number of lines' ,
249- default = 10 , type = int , nargs = '?' )
250- parser_log .add_argument ('log_level' , help = 'logging level' , choices = [i .name for i in LogLevel ], default = 'INFO' , nargs = '?' )
251- parser_log .set_defaults (func = self .read_bot_log )
252-
253- parser_run = subparsers .add_parser ('run' , help = 'Run a bot interactively' )
254- parser_run .add_argument ('bot_id' , choices = self ._configured_bots_list ())
255- parser_run .add_argument ('--loglevel' , '-l' , nargs = '?' , default = None , choices = [i .name for i in LogLevel ])
256- parser_run_subparsers = parser_run .add_subparsers (title = 'run-subcommands' )
257-
258- parser_run_console = parser_run_subparsers .add_parser ('console' , help = 'Get a ipdb live console.' )
259- parser_run_console .add_argument ('console_type' , nargs = '?' ,
260- help = 'You may specify which console should be run. Default is ipdb (if installed)'
261- ' or pudb (if installed) or pdb but you may want to use another one.' )
262- parser_run_console .set_defaults (run_subcommand = "console" )
263-
264- parser_run_message = parser_run_subparsers .add_parser ('message' ,
265- help = 'Debug bot\' s pipelines. Get the message in the'
266- ' input pipeline, pop it (cut it) and display it, or'
267- ' send the message directly to bot\' s output pipeline(s).' )
268- parser_run_message .add_argument ('message_action_kind' ,
269- choices = ["get" , "pop" , "send" ],
270- help = 'get: show the next message in the source pipeline. '
271- 'pop: show and delete the next message in the source pipeline '
272- 'send: Send the given message to the destination pipeline(s).' )
273- parser_run_message .add_argument ('msg' , nargs = '?' , help = 'If send was chosen, put here the message in JSON.' )
274- parser_run_message .set_defaults (run_subcommand = "message" )
275-
276- parser_run_process = parser_run_subparsers .add_parser ('process' , help = 'Single run of bot\' s process() method.' )
277- parser_run_process .add_argument ('--show-sent' , '-s' , action = 'store_true' ,
278- help = 'If message is sent through, displays it.' )
279- parser_run_process .add_argument ('--dryrun' , '-d' , action = 'store_true' ,
280- help = 'Never really pop the message from the input pipeline '
281- 'nor send to output pipeline.' )
282- parser_run_process .add_argument ('--msg' , '-m' ,
283- help = 'Trick the bot to process this JSON '
284- 'instead of the Message in its pipeline.' )
285- parser_run_process .set_defaults (run_subcommand = "process" )
286- parser_run .set_defaults (func = self .bot_run )
287-
288- parser_check = subparsers .add_parser ('check' ,
289- help = 'Check installation and configuration' )
290- parser_check .add_argument ('--quiet' , '-q' , action = 'store_true' ,
291- help = 'Only print warnings and errors.' )
292- parser_check .add_argument ('--no-connections' , '-C' , action = 'store_true' ,
293- help = 'Do not test the connections to services like redis.' )
294- parser_check .set_defaults (func = self .check )
295-
296- parser_help = subparsers .add_parser ('help' ,
297- help = 'Show the help' )
298- parser_help .set_defaults (func = parser .print_help )
299-
300- parser_start = subparsers .add_parser ('start' , help = 'Start a bot or botnet' )
301- parser_start .add_argument ('bot_id' , nargs = '?' ,
302- choices = self ._configured_bots_list ())
303- parser_start .add_argument ('--group' , help = 'Start a group of bots' ,
304- choices = BOT_GROUP .keys ())
305- parser_start .set_defaults (func = self .bot_start )
306-
307- parser_stop = subparsers .add_parser ('stop' , help = 'Stop a bot or botnet' )
308- parser_stop .add_argument ('bot_id' , nargs = '?' ,
309- choices = self ._configured_bots_list ())
310- parser_stop .add_argument ('--group' , help = 'Stop a group of bots' ,
311- choices = BOT_GROUP .keys ())
312- parser_stop .set_defaults (func = self .bot_stop )
313-
314- parser_restart = subparsers .add_parser ('restart' , help = 'Restart a bot or botnet' )
315- parser_restart .add_argument ('bot_id' , nargs = '?' ,
316- choices = self ._configured_bots_list ())
317- parser_restart .add_argument ('--group' , help = 'Restart a group of bots' ,
318- choices = BOT_GROUP .keys ())
319- parser_restart .set_defaults (func = self .bot_restart )
320-
321- parser_reload = subparsers .add_parser ('reload' , help = 'Reload a bot or botnet' )
322- parser_reload .add_argument ('bot_id' , nargs = '?' ,
323- choices = self ._configured_bots_list ())
324- parser_reload .add_argument ('--group' , help = 'Reload a group of bots' ,
325- choices = BOT_GROUP .keys ())
326- parser_reload .set_defaults (func = self .bot_reload )
327-
328- parser_status = subparsers .add_parser ('status' , help = 'Status of a bot or botnet' )
329- parser_status .add_argument ('bot_id' , nargs = '?' ,
330- choices = self ._configured_bots_list ())
331- parser_status .add_argument ('--group' , help = 'Get status of a group of bots' ,
332- choices = BOT_GROUP .keys ())
333- parser_status .set_defaults (func = self .bot_status )
334-
335- parser_status = subparsers .add_parser ('enable' , help = 'Enable a bot' )
336- parser_status .add_argument ('bot_id' ,
337- choices = self ._configured_bots_list ())
338- parser_status .set_defaults (func = self .bot_enable )
339-
340- parser_status = subparsers .add_parser ('disable' , help = 'Disable a bot' )
341- parser_status .add_argument ('bot_id' ,
342- choices = self ._configured_bots_list ())
343- parser_status .set_defaults (func = self .bot_disable )
344-
345- parser_upgrade_conf = subparsers .add_parser ('upgrade-config' ,
346- help = 'Upgrade IntelMQ configuration to a newer version.' )
347- parser_upgrade_conf .add_argument ('-p' , '--previous' ,
348- help = 'Use this version as the previous one.' )
349- parser_upgrade_conf .add_argument ('-d' , '--dry-run' ,
350- action = 'store_true' , default = False ,
351- help = 'Do not write any files.' )
352- parser_upgrade_conf .add_argument ('-u' , '--function' ,
353- help = 'Run this upgrade function.' ,
354- choices = upgrades .__all__ )
355- parser_upgrade_conf .add_argument ('-f' , '--force' ,
356- action = 'store_true' ,
357- help = 'Force running the upgrade procedure.' )
358- parser_upgrade_conf .add_argument ('--state-file' ,
359- help = 'The state file location to use.' ,
360- default = STATE_FILE_PATH )
361- parser_upgrade_conf .add_argument ('--no-backup' ,
362- help = 'Do not create backups of state and configuration files.' ,
363- action = 'store_true' )
364- parser_upgrade_conf .set_defaults (func = self .upgrade_conf )
365-
366- parser_debug = subparsers .add_parser ('debug' , help = 'Get debugging output.' )
367- parser_debug .add_argument ('--get-paths' , help = 'Give all paths' ,
368- action = 'append_const' , dest = 'sections' ,
369- const = 'paths' )
370- parser_debug .add_argument ('--get-environment-variables' ,
371- help = 'Give environment variables' ,
372- action = 'append_const' , dest = 'sections' ,
373- const = 'environment_variables' )
374- parser_debug .set_defaults (func = self .debug )
375-
376- self .parser = parser
219+ self .parser = mrun (get_parser (self , self ._configured_bots_list (), BOT_GROUP .keys (), upgrades .__all__ ),
220+ prog = APPNAME , description = DESCRIPTION , epilog = EPILOG ,
221+ add_version = VERSION )
377222 else :
378223 self ._processmanager = process_managers ()[self ._processmanagertype ](
379224 self ._interactive ,
@@ -404,15 +249,11 @@ def load_defaults_configuration(self, silent=False):
404249 setattr (self ._parameters , option , value )
405250
406251 def run (self ):
407- results = None
408- args = self .parser .parse_args ()
409- if 'func' not in args :
410- sys .exit (self .parser .print_help ())
411- args_dict = vars (args ).copy ()
252+ m = self .parser
253+ args = m .env
412254
413255 self ._quiet = args .quiet
414- self ._returntype = ReturnType [args .type .upper ()]
415- del args_dict ['type' ], args_dict ['quiet' ], args_dict ['func' ]
256+ self ._returntype = args .type
416257
417258 self ._logging_level = 'WARNING' if self ._quiet else 'INFO'
418259 self ._logger .setLevel (self ._logging_level )
@@ -427,7 +268,7 @@ def run(self):
427268 self ._quiet
428269 )
429270
430- retval , results = args .func ( ** args_dict )
271+ retval , results = run_handler ( args .command )
431272
432273 if self ._returntype is ReturnType .JSON :
433274 print (json .dumps (results , indent = 4 ))
@@ -438,6 +279,14 @@ def bot_run(self, **kwargs):
438279 # the bot_run method is special in that it mixes plain text
439280 # and json in its output, therefore it is printed here
440281 # and not in the calling `run` method.
282+
283+ # Adapt to newer interface. NOTE we should rather refactor the _processmanager.bot_run to accept these parameters.
284+ subc = kwargs ["subcommand" ]
285+ del kwargs ["subcommand" ]
286+ if kwargs ["loglevel" ]:
287+ kwargs ["loglevel" ] = kwargs ["loglevel" ].value
288+ kwargs = {** kwargs , ** subc }
289+
441290 retval , results = self ._processmanager .bot_run (** kwargs )
442291 print (results )
443292 return retval , None
0 commit comments