diff --git a/scripts/policy/frameworks/management/agent/__load__.zeek b/scripts/policy/frameworks/management/agent/__load__.zeek index 590325ed9a..4c8ed9224f 100644 --- a/scripts/policy/frameworks/management/agent/__load__.zeek +++ b/scripts/policy/frameworks/management/agent/__load__.zeek @@ -12,5 +12,6 @@ @endif @if ( Supervisor::is_supervisor() ) +@load policy/frameworks/management/supervisor @load ./boot @endif diff --git a/scripts/policy/frameworks/management/agent/boot.zeek b/scripts/policy/frameworks/management/agent/boot.zeek index ead12665f2..cd1e302c76 100644 --- a/scripts/policy/frameworks/management/agent/boot.zeek +++ b/scripts/policy/frameworks/management/agent/boot.zeek @@ -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"; diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index a7323eedbd..efeb680539 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -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" ) diff --git a/scripts/policy/frameworks/management/controller/boot.zeek b/scripts/policy/frameworks/management/controller/boot.zeek index 6470385d94..e117583e1e 100644 --- a/scripts/policy/frameworks/management/controller/boot.zeek +++ b/scripts/policy/frameworks/management/controller/boot.zeek @@ -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"; diff --git a/scripts/policy/frameworks/management/controller/main.zeek b/scripts/policy/frameworks/management/controller/main.zeek index 468cc71bab..ba35619a6c 100644 --- a/scripts/policy/frameworks/management/controller/main.zeek +++ b/scripts/policy/frameworks/management/controller/main.zeek @@ -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.