zeek/policy/frameworks/cluster/send-config.bro
Seth Hall be65acec4e Initial commit of the new cluster framework.
- It's ok to always load the framework.  If you don't
  specifiy the CLUSTER_NODE environment variable it doesn't
  ultimately do anything.
- The $CLUSTER_NODE variable causes the framework to try and
  load a script named cluster-layout.bro which must be located
  somewhere in your $BROPATH.  The value of the $CLUSTER_NODE
  variable is a count that indicates a node in the Cluster::nodes
  variable that is set in the cluster-layout.bro script.
- The Cluster::nodes variable is a flat configuration because
  it's assumed that it would be automatically generated by a
  utility such as BroControl.  This will facilitate the tiered or
  "deep" clustering that is coming.
2011-07-07 13:21:19 -04:00

108 lines
2.8 KiB
Text

##! This is a utility script that sends the current values of all &redef'able
##! consts to a remote Bro then sends the :bro:id:`configuration_update` event
##! and terminates processing.
##!
##! Intended to be used from the command line as in:
##! bro Cluster::config_node=<node> <scripts> frameworks/cluster/send-config
##!
##! The :bro:id:`config_node` value should contain the node name of one of the
##! nodes of the configured cluster.
@load frameworks/communication
@load frameworks/cluster
module Cluster;
export {
## This is the name of the node configured in the cluster that the
## updated configuration should be sent to.
const config_node = "" &redef;
## Variable IDs that are to be ignored by the update process.
const ignore_ids: set[string] = {
"Communication::nodes",
"Cluster::config_node"
};
}
event terminate_event()
{
terminate_communication();
}
event remote_connection_handshake_done(p: event_peer)
{
local peer = Communication::nodes[config_node];
if ( peer$host != p$host )
return;
# Send all &redef'able consts to the peer.
local globals = global_ids();
local cnt = 0;
for ( id in globals )
{
if ( id in ignore_ids )
next;
local t = globals[id];
# Skip it if the variable isn't redefinable or not const.
# We don't want to update non-const globals because that's usually
# where state is stored and those values will frequently be declared
# with &redef so that attributes can be redefined.
if ( ! t$redefinable || ! t$constant )
next;
send_id(p, id);
++cnt;
}
print fmt("sent %d IDs", cnt);
# Signal configuration update to peer.
event configuration_update();
# We can't terminate the communication right away here since the
# event configuration_update is only queued but not send at this
# point. Therefore we raise another events which will trigger
# termination only after the previous has been raised.
event terminate_event();
}
function make_dest(tag: string, ip: addr, p: port)
{
Communication::nodes[fmt("%s-update", tag)]
= [$host=ip, $p=p, $sync=F, $class="update"];
}
# This handler is executed after the other bro_inits() so that we can
# actually delete all previous destinations and fill the table ourselves.
event bro_init() &priority=-1
{
clear_table(Communication::nodes);
for ( n in workers )
make_dest(workers[n]$tag, workers[n]$ip, workers[n]$p);
for ( n in proxies )
make_dest(proxies[n]$tag, proxies[n]$ip, proxies[n]$p);
make_dest(manager$tag, manager$ip, manager$p);
}
event bro_init() &priority=-2
{
if ( config_node !in Communication::nodes )
{
if ( config_node == "" )
print "You must supply a value to the Cluster::config_node variable.";
else
print fmt("Unknown peer '%s'", config_node);
terminate();
return;
}
Communication::connect_peer(config_node);
}