From 4e862cae9a0c3e90e64ef8dc6c30ea26de95e7e3 Mon Sep 17 00:00:00 2001 From: Christian Kreibich Date: Fri, 22 Mar 2024 19:29:17 -0700 Subject: [PATCH] Introduce metrics_port to supervisor and management framework. This only adds the port value in the various required places. Its actual use follows in the next commits. --- scripts/base/frameworks/supervisor/api.zeek | 2 ++ .../frameworks/management/agent/main.zeek | 6 +++++ .../policy/frameworks/management/types.zeek | 3 +++ src/supervisor/Supervisor.cc | 22 +++++++++++++++++++ src/supervisor/Supervisor.h | 4 ++++ 5 files changed, 37 insertions(+) diff --git a/scripts/base/frameworks/supervisor/api.zeek b/scripts/base/frameworks/supervisor/api.zeek index 97a286f8c9..e3a6d06c9b 100644 --- a/scripts/base/frameworks/supervisor/api.zeek +++ b/scripts/base/frameworks/supervisor/api.zeek @@ -30,6 +30,8 @@ export { ## The PCAP file name from which the node will read/analyze packets. ## Typically used by worker nodes. pcap_file: string &optional; + ## The TCP port at which the cluster node exposes metrics for Prometheus. + metrics_port: port &optional; }; ## Configuration options that influence behavior of a supervised Zeek node. diff --git a/scripts/policy/frameworks/management/agent/main.zeek b/scripts/policy/frameworks/management/agent/main.zeek index 6397313eab..cd648f0c5b 100644 --- a/scripts/policy/frameworks/management/agent/main.zeek +++ b/scripts/policy/frameworks/management/agent/main.zeek @@ -521,6 +521,9 @@ function deploy_request_finish(areq: Management::Request::Request) if ( node?$interface ) cep$interface = node$interface; + if ( node?$metrics_port ) + cep$metrics_port = node$metrics_port; + g_cluster[node$name] = cep; } @@ -630,6 +633,9 @@ function get_nodes_request_finish(areq: Management::Request::Request) # serialization always assumes TCP. if ( sns$node$cluster[node]$p != 0/tcp ) cns$p = sns$node$cluster[node]$p; + + if ( sns$node$cluster[node]?$metrics_port ) + cns$metrics_port = sns$node$cluster[node]$metrics_port; } else { diff --git a/scripts/policy/frameworks/management/types.zeek b/scripts/policy/frameworks/management/types.zeek index 796c943754..aa5c8656e4 100644 --- a/scripts/policy/frameworks/management/types.zeek +++ b/scripts/policy/frameworks/management/types.zeek @@ -60,6 +60,7 @@ export { interface: string &optional; ##< Interface to sniff cpu_affinity: int &optional; ##< CPU/core number to pin to env: table[string] of string &default=table(); ##< Custom environment vars + metrics_port: port &optional; ##< Metrics exposure port for Prometheus }; ## Data structure capturing a cluster's complete configuration. @@ -88,6 +89,8 @@ export { pid: int &optional; ## The node's Broker peering listening port, if any. p: port &optional; + ## The node's metrics port for Prometheus, if any. + metrics_port: port &optional; }; type NodeStatusVec: vector of NodeStatus; diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index a176f033e3..8e73b5aa1f 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1269,6 +1269,11 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) if ( pcap_file ) ep.pcap_file = pcap_file->AsStringVal()->ToStdString(); + const auto& metrics_port = rv->GetField("metrics_port"); + + if ( metrics_port ) + ep.metrics_port = rv->GetFieldAs("metrics_port")->Port(); + rval.cluster.emplace(name, std::move(ep)); } @@ -1337,6 +1342,9 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromJSON(std::string_view json) { if ( auto it = val.FindMember("pcap_file"); it != val.MemberEnd() ) ep.pcap_file = it->value.GetString(); + if ( auto it = val.FindMember("metrics_port"); it != val.MemberEnd() ) + ep.metrics_port = it->value["port"].GetInt(); + rval.cluster.emplace(key, std::move(ep)); } @@ -1421,6 +1429,9 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const { if ( ep.pcap_file ) val->AssignField("pcap_file", *ep.pcap_file); + if ( ep.metrics_port ) + val->AssignField("metrics_port", val_mgr->Port(*ep.metrics_port, TRANSPORT_TCP)); + cluster_val->Assign(std::move(key), std::move(val)); } @@ -1488,6 +1499,9 @@ bool SupervisedNode::InitCluster() const { if ( manager_name && ep.role != BifEnum::Supervisor::MANAGER ) val->AssignField("manager", *manager_name); + if ( ep.metrics_port ) + val->AssignField("metrics_port", val_mgr->Port(*ep.metrics_port, TRANSPORT_TCP)); + cluster_nodes->Assign(std::move(key), std::move(val)); } @@ -1551,6 +1565,14 @@ void SupervisedNode::Init(Options* options) const { fprintf(stderr, "node '%s' failed to setenv: %s\n", node_name.data(), strerror(errno)); exit(1); } + + if ( const auto& ep = config.cluster.find(node_name); ep != config.cluster.end() && ep->second.metrics_port ) { + auto metrics_port_str = std::to_string(*(ep->second.metrics_port)); + if ( setenv("ZEEK_METRICS_PORT", metrics_port_str.c_str(), true) == -1 ) { + fprintf(stderr, "metrics port '%s' failed to setenv: %s\n", metrics_port_str.c_str(), strerror(errno)); + exit(1); + } + } } options->filter_supervised_node_options(); diff --git a/src/supervisor/Supervisor.h b/src/supervisor/Supervisor.h index aa511e1209..9ec2f976ca 100644 --- a/src/supervisor/Supervisor.h +++ b/src/supervisor/Supervisor.h @@ -137,6 +137,10 @@ public: * Typically used by worker nodes. */ std::optional pcap_file; + /** + * The TCP port number at which the cluster node exposes metrics for Prometheus. + */ + std::optional metrics_port; }; /**