Management framework: enable stdout/stderr reporting

This uses the new frameworks/management/supervisor functionality to maintain
stdout/stderr files, and hooks output context into set_configuration error
results.
This commit is contained in:
Christian Kreibich 2022-05-30 18:51:15 -07:00
parent 24a495da42
commit f10b94de39
5 changed files with 34 additions and 17 deletions

View file

@ -12,5 +12,6 @@
@endif
@if ( Supervisor::is_supervisor() )
@load policy/frameworks/management/supervisor
@load ./boot
@endif

View file

@ -39,10 +39,9 @@ event zeek_init()
if ( ! mkdir(sn$directory) )
print(fmt("warning: could not create agent state dir '%s'", sn$directory));
if ( Management::Agent::stdout_file != "" )
sn$stdout_file = Management::Agent::stdout_file;
if ( Management::Agent::stderr_file != "" )
sn$stderr_file = Management::Agent::stderr_file;
# We don't set sn$stdout_file/stderr_file here because the Management
# framework's Supervisor shim manages those output files itself. See
# frameworks/management/supervisor/main.zeek for details.
# This helps identify Management framework nodes reliably.
sn$env["ZEEK_MANAGEMENT_NODE"] = "AGENT";

View file

@ -9,6 +9,8 @@
@load policy/frameworks/management
@load policy/frameworks/management/node/api
@load policy/frameworks/management/node/config
@load policy/frameworks/management/supervisor/api
@load policy/frameworks/management/supervisor/config
@load ./api
@load ./config
@ -91,6 +93,10 @@ global g_config_reqid_pending: string = "";
# configurations.
global g_cluster: table[string] of Supervisor::ClusterEndpoint;
# The most recent output contexts we've received from the Supervisor, for
# any of our nodes.
global g_outputs: table[string] of Management::NodeOutputs;
function agent_topic(): string
{
@ -113,11 +119,12 @@ function send_set_configuration_response(req: Management::Request::Request)
if ( node in req$set_configuration_state_agent$nodes_pending )
{
# This node failed. Pull in any stdout/stderr context
# we might have.
# This node failed.
res$success = F;
# XXX fill in stdout/stderr here if possible
# Pull in any stdout/stderr context we might have.
if ( node in g_outputs )
res$data = g_outputs[node];
}
# Add this result to the overall response
@ -135,6 +142,12 @@ function send_set_configuration_response(req: Management::Request::Request)
g_config_reqid_pending = "";
}
event Management::Supervisor::API::notify_node_exit(node: string, outputs: Management::NodeOutputs)
{
if ( node in g_nodes )
g_outputs[node] = outputs;
}
event SupervisorControl::create_response(reqid: string, result: string)
{
local req = Management::Request::lookup(reqid);
@ -315,10 +328,10 @@ event Management::Agent::API::set_configuration_request(reqid: string, config: M
# node.
nc$scripts[|nc$scripts|] = "policy/frameworks/management/node";
if ( Management::Node::stdout_file != "" )
nc$stdout_file = Management::Node::stdout_file;
if ( Management::Node::stderr_file != "" )
nc$stderr_file = Management::Node::stderr_file;
# We don't set nc$stdout_file/stderr_file here because the
# Management framework's Supervisor shim manages those output
# files itself. See frameworks/management/supervisor/main.zeek
# for details.
# XXX could use options to enable per-node overrides for
# directory, stdout, stderr, others?
@ -708,6 +721,7 @@ event zeek_init()
Broker::subscribe(agent_topic());
Broker::subscribe(SupervisorControl::topic_prefix);
Broker::subscribe(Management::Node::node_topic);
Broker::subscribe(Management::Supervisor::topic_prefix);
# Establish connectivity with the controller.
if ( Management::Agent::controller$address != "0.0.0.0" )

View file

@ -34,10 +34,9 @@ event zeek_init()
if ( ! mkdir(sn$directory) )
print(fmt("warning: could not create controller state dir '%s'", sn$directory));
if ( Management::Controller::stdout_file != "" )
sn$stdout_file = Management::Controller::stdout_file;
if ( Management::Controller::stderr_file != "" )
sn$stderr_file = Management::Controller::stderr_file;
# We don't set sn$stdout_file/stderr_file here because the Management
# framework's Supervisor shim manages those output files itself. See
# frameworks/management/supervisor/main.zeek for details.
# This helps identify Management framework nodes reliably.
sn$env["ZEEK_MANAGEMENT_NODE"] = "CONTROLLER";

View file

@ -363,11 +363,15 @@ event Management::Agent::API::set_configuration_response(reqid: string, results:
if ( Management::Request::is_null(req) )
return;
# XXX the usual "any" handling needs to happen here if data is filled in
# Add this agent's results to the overall response
for ( i in results )
{
# The usual "any" treatment to keep access predictable
if ( results[i]?$data )
results[i]$data = results[i]$data as Management::NodeOutputs;
req$results[|req$results|] = results[i];
}
# Mark this request as done by removing it from the table of pending
# ones. The following if-check should always be true.