##! File input for the configuration framework using the input framework. @load ./main @load base/frameworks/cluster module Config; export { ## Configuration files that will be read off disk. Files are reread ## every time they are updated so updates should be atomic with "mv" ## instead of writing the file in place. ## ## If the same configuration option is defined in several files with ## different values, behavior is unspecified. const config_files: set[string] = {} &redef; ## Read specified configuration file and apply values; updates to file ## are not tracked. global read_config: function(filename: string); } global current_config: table[string] of string = table(); type ConfigItem: record { option_nv: string; }; type EventFields: record { option_name: string; option_val: string; }; event config_line(description: Input::EventDescription, tpe: Input::Event, p: EventFields) { } event zeek_init() &priority=5 { if ( Cluster::is_enabled() && Cluster::local_node_type() != Cluster::MANAGER ) return; for ( fi in config_files ) Input::add_table(Input::TableDescription($reader=Input::READER_CONFIG, $mode=Input::REREAD, $source=fi, $name=cat("config-", fi), $idx=ConfigItem, $val=ConfigItem, $want_record=F, $destination=current_config)); } event InputConfig::new_value(name: string, source: string, id: string, value: any) { if ( sub_bytes(name, 1, 15) != "config-oneshot-" && source !in config_files ) return; Config::set_value(id, value, source); } function read_config(filename: string) { # Only read the configuration on the manager. The other nodes are being fed # from the manager. if ( Cluster::is_enabled() && Cluster::local_node_type() != Cluster::MANAGER ) return; local iname = cat("config-oneshot-", filename); Input::add_event(Input::EventDescription($reader=Input::READER_CONFIG, $mode=Input::MANUAL, $source=filename, $name=iname, $fields=EventFields, $ev=config_line)); Input::remove(iname); }