17
17
import click
18
18
from elasticsearch import Elasticsearch
19
19
from eql import load_dump
20
- from kibana .connector import Kibana
21
20
21
+ from kibana .connector import Kibana
22
22
from . import rule_loader
23
+ from .cli_utils import single_collection
23
24
from .eswrap import CollectEvents , add_range_to_dsl
24
25
from .main import root
25
26
from .misc import PYTHON_LICENSE , add_client , GithubClient , Manifest , client_error , getdefault
26
27
from .packaging import PACKAGE_FILE , Package , manage_versions , RELEASE_DIR
27
- from .rule import TOMLRule , TOMLRuleContents , BaseQueryRuleData
28
- from .rule_loader import get_rule
28
+ from .rule import TOMLRule , BaseQueryRuleData
29
+ from .rule_loader import production_filter , RuleCollection
29
30
from .utils import get_path , dict_hash
30
31
31
32
RULES_DIR = get_path ('rules' )
@@ -68,7 +69,7 @@ def update_lock_versions(rule_ids):
68
69
if not click .confirm ('Are you sure you want to update hashes without a version bump?' ):
69
70
return
70
71
71
- rules = [ r for r in rule_loader . load_rules ( verbose = False ). values () if r .id in rule_ids ]
72
+ rules = RuleCollection . default (). filter ( lambda r : r .id in rule_ids )
72
73
changed , new = manage_versions (rules , exclude_version_update = True , add_new = False , save_changes = True )
73
74
74
75
if not changed :
@@ -86,10 +87,12 @@ def kibana_diff(rule_id, repo, branch, threads):
86
87
"""Diff rules against their version represented in kibana if exists."""
87
88
from .misc import get_kibana_rules
88
89
90
+ rules = RuleCollection .default ()
91
+
89
92
if rule_id :
90
- rules = { r . id : r for r in rule_loader . load_rules ( verbose = False ). values () if r . id in rule_id }
93
+ rules = rules . filter ( lambda r : r . id in rule_id )
91
94
else :
92
- rules = { r . id : r for r in rule_loader . get_production_rules ()}
95
+ rules = rules . filter ( production_filter )
93
96
94
97
# add versions to the rules
95
98
manage_versions (list (rules .values ()), verbose = False )
@@ -102,13 +105,13 @@ def kibana_diff(rule_id, repo, branch, threads):
102
105
missing_from_kibana = list (set (repo_hashes ).difference (set (kibana_hashes )))
103
106
104
107
rule_diff = []
105
- for rid , rhash in repo_hashes .items ():
106
- if rid in missing_from_kibana :
108
+ for rule_id , rule_hash in repo_hashes .items ():
109
+ if rule_id in missing_from_kibana :
107
110
continue
108
- if rhash != kibana_hashes [rid ]:
111
+ if rule_hash != kibana_hashes [rule_id ]:
109
112
rule_diff .append (
110
- f'versions - repo: { rules [rid ].contents ["version" ]} , kibana: { kibana_rules [rid ]["version" ]} -> '
111
- f'{ rid } - { rules [rid ].name } '
113
+ f'versions - repo: { rules [rule_id ].contents ["version" ]} , kibana: { kibana_rules [rule_id ]["version" ]} -> '
114
+ f'{ rule_id } - { rules [rule_id ].name } '
112
115
)
113
116
114
117
diff = {
@@ -373,26 +376,17 @@ def event_search(query, index, language, date_range, count, max_results, verbose
373
376
374
377
375
378
@test_group .command ('rule-event-search' )
376
- @click .argument ('rule-file' , type = click .Path (dir_okay = False ), required = False )
377
- @click .option ('--rule-id' , '-id' )
379
+ @single_collection
378
380
@click .option ('--date-range' , '-d' , type = (str , str ), default = ('now-7d' , 'now' ), help = 'Date range to scope search' )
379
381
@click .option ('--count' , '-c' , is_flag = True , help = 'Return count of results only' )
380
382
@click .option ('--max-results' , '-m' , type = click .IntRange (1 , 1000 ), default = 100 ,
381
383
help = 'Max results to return (capped at 1000)' )
382
384
@click .option ('--verbose' , '-v' , is_flag = True )
383
385
@click .pass_context
384
386
@add_client ('elasticsearch' )
385
- def rule_event_search (ctx , rule_file , rule_id , date_range , count , max_results , verbose ,
387
+ def rule_event_search (ctx , rule , date_range , count , max_results , verbose ,
386
388
elasticsearch_client : Elasticsearch = None ):
387
389
"""Search using a rule file against an Elasticsearch instance."""
388
- rule : TOMLRule
389
-
390
- if rule_id :
391
- rule = get_rule (rule_id , verbose = False )
392
- elif rule_file :
393
- rule = TOMLRule (path = rule_file , contents = TOMLRuleContents .from_dict (load_dump (rule_file )))
394
- else :
395
- client_error ('Must specify a rule file or rule ID' )
396
390
397
391
if isinstance (rule .contents .data , BaseQueryRuleData ):
398
392
if verbose :
@@ -431,18 +425,17 @@ def rule_survey(ctx: click.Context, query, date_range, dump_file, hide_zero_coun
431
425
"""Survey rule counts."""
432
426
from eql .table import Table
433
427
from kibana .resources import Signal
434
- from . import rule_loader
435
428
from .main import search_rules
436
429
437
430
survey_results = []
438
431
start_time , end_time = date_range
439
432
440
433
if query :
441
- rule_paths = [ r [ 'file' ] for r in ctx . invoke ( search_rules , query = query , verbose = False )]
442
- rules = rule_loader . load_rules ( rule_loader . load_rule_files ( paths = rule_paths , verbose = False ) , verbose = False )
443
- rules = rules . values ( )
434
+ rules = RuleCollection ()
435
+ paths = [ Path ( r [ 'file' ]) for r in ctx . invoke ( search_rules , query = query , verbose = False )]
436
+ rules . load_files ( paths )
444
437
else :
445
- rules = rule_loader . load_rules ( verbose = False ). values ( )
438
+ rules = RuleCollection . default (). filter ( production_filter )
446
439
447
440
click .echo (f'Running survey against { len (rules )} rules' )
448
441
click .echo (f'Saving detailed dump to: { dump_file } ' )
0 commit comments