Skip to content

Commit 3e66b9a

Browse files
committed
Add bound and advertised addresses to GetIdent
Adds bound_addresses and advertised_addresses to GetIdent responses to enable tools and automations to extract that information for future use.
1 parent 21e515f commit 3e66b9a

File tree

4 files changed

+171
-13
lines changed

4 files changed

+171
-13
lines changed

crates/core/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
2828

2929
tonic_prost_build::configure()
3030
.bytes(".")
31+
.enum_attribute("AddressKind", "#[derive(::serde::Serialize)]")
32+
.enum_attribute("AddressKind", "#[serde(rename_all = \"kebab-case\")]")
3133
.file_descriptor_set_path(out_dir.join("node_ctl_svc_descriptor.bin"))
3234
// allow older protobuf compiler to be used
3335
.protoc_arg("--experimental_allow_proto3_optional")

crates/core/protobuf/node_ctl_svc.proto

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ message ProvisionClusterResponse {
5555
}
5656

5757
message IdentResponse {
58+
enum AddressKind {
59+
UNKNOWN = 0;
60+
TCP = 1;
61+
HTTP = 2;
62+
UNIX = 3;
63+
}
64+
message NetAddress {
65+
string name = 1;
66+
string address = 2;
67+
AddressKind kind = 3;
68+
}
5869
restate.common.NodeStatus status = 1;
5970
// node id may be unset if the node hasn't yet joined a cluster
6071
optional restate.common.NodeId node_id = 2;
@@ -72,6 +83,8 @@ message IdentResponse {
7283
uint32 logs_version = 11;
7384
uint32 schema_version = 12;
7485
uint32 partition_table_version = 13;
86+
repeated NetAddress bound_addresses = 14;
87+
repeated NetAddress advertised_addresses = 15;
7588
}
7689

7790
message GetMetadataRequest {

crates/core/src/identification.rs

Lines changed: 146 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// the Business Source License, use of this software will be governed
99
// by the Apache License, Version 2.0.
1010

11+
// re-export the AddressKind enum from the protobuf
12+
pub use crate::protobuf::node_ctl_svc::ident_response::AddressKind as NetAddressKind;
13+
1114
use std::time::Duration;
1215

1316
use enumset::EnumSet;
@@ -18,6 +21,11 @@ use restate_types::config::Configuration;
1821
use restate_types::health::{
1922
AdminStatus, LogServerStatus, MetadataServerStatus, NodeStatus, WorkerStatus,
2023
};
24+
use restate_types::net::address::{
25+
AdminPort, AdvertisedAddress, ControlPort, FabricPort, HttpIngressPort, ListenerPort,
26+
PeerNetAddress,
27+
};
28+
use restate_types::net::listener::{AddressBook, Addresses};
2129
use restate_types::nodes_config::Role;
2230
use restate_types::{NodeId, Version};
2331

@@ -45,6 +53,16 @@ pub struct Identification {
4553
pub logs_version: Version,
4654
pub schema_version: Version,
4755
pub partition_table_version: Version,
56+
pub bound_addresses: Vec<NetAddress>,
57+
pub advertised_addresses: Vec<NetAddress>,
58+
}
59+
60+
#[derive(serde::Serialize, prost_dto::IntoProst)]
61+
#[prost(target = "crate::protobuf::node_ctl_svc::ident_response::NetAddress")]
62+
pub struct NetAddress {
63+
pub name: String,
64+
pub address: String,
65+
pub kind: NetAddressKind,
4866
}
4967

5068
fn enum_set_to_vec(roles: &EnumSet<Role>) -> Vec<String> {
@@ -55,20 +73,34 @@ impl Identification {
5573
/// Gets the identification information for this node. It needs to be called from within the
5674
/// [`TaskCenter`].
5775
pub fn get() -> Self {
58-
let (node_status, admin_status, worker_status, metadata_server_status, log_server_status) =
59-
TaskCenter::with_current(|tc| {
60-
let health = tc.health();
61-
(
62-
health.current_node_status(),
63-
health.current_admin_status(),
64-
health.current_worker_status(),
65-
health.current_metadata_store_status(),
66-
health.current_log_server_status(),
67-
)
68-
});
76+
let configuration = Configuration::pinned();
77+
78+
let (
79+
node_status,
80+
admin_status,
81+
worker_status,
82+
metadata_server_status,
83+
log_server_status,
84+
bound_addresses,
85+
advertised_addresses,
86+
) = TaskCenter::with_current(|tc| {
87+
let health = tc.health();
88+
let address_book = tc.address_book();
89+
90+
let bound_addresses = collect_bound_addresses(address_book);
91+
let advertised_addresses = collect_advertised_addresses(&configuration, address_book);
92+
(
93+
health.current_node_status(),
94+
health.current_admin_status(),
95+
health.current_worker_status(),
96+
health.current_metadata_store_status(),
97+
health.current_log_server_status(),
98+
bound_addresses,
99+
advertised_addresses,
100+
)
101+
});
69102
let age = TaskCenter::with_current(|tc| tc.age());
70103
let metadata = Metadata::current();
71-
let configuration = Configuration::pinned();
72104

73105
Identification {
74106
status: node_status,
@@ -84,6 +116,108 @@ impl Identification {
84116
logs_version: metadata.logs_version(),
85117
schema_version: metadata.schema_version(),
86118
partition_table_version: metadata.partition_table_version(),
119+
bound_addresses,
120+
advertised_addresses,
87121
}
88122
}
89123
}
124+
125+
fn collect_bound_addresses(address_book: &AddressBook) -> Vec<NetAddress> {
126+
let mut addresses = Vec::with_capacity(4);
127+
128+
push_addresses(
129+
address_book.get_bound_addresses::<HttpIngressPort>(),
130+
&mut addresses,
131+
);
132+
133+
push_addresses(
134+
address_book.get_bound_addresses::<AdminPort>(),
135+
&mut addresses,
136+
);
137+
138+
push_addresses(
139+
address_book.get_bound_addresses::<FabricPort>(),
140+
&mut addresses,
141+
);
142+
143+
push_addresses(
144+
address_book.get_bound_addresses::<ControlPort>(),
145+
&mut addresses,
146+
);
147+
148+
addresses
149+
}
150+
151+
fn collect_advertised_addresses(
152+
config: &Configuration,
153+
address_book: &AddressBook,
154+
) -> Vec<NetAddress> {
155+
let mut addresses = Vec::with_capacity(3);
156+
157+
if config.has_role(Role::HttpIngress) {
158+
push_advertised(
159+
config.ingress.advertised_address(address_book),
160+
&mut addresses,
161+
);
162+
}
163+
164+
if config.has_role(Role::Admin) {
165+
push_advertised(
166+
config.admin.advertised_address(address_book),
167+
&mut addresses,
168+
);
169+
}
170+
171+
// fabric
172+
push_advertised(
173+
config.common.advertised_address(address_book),
174+
&mut addresses,
175+
);
176+
177+
addresses
178+
}
179+
180+
#[inline(always)]
181+
fn push_addresses<P: ListenerPort + 'static>(
182+
address: Option<Addresses<P>>,
183+
buf: &mut Vec<NetAddress>,
184+
) {
185+
let Some(addresses) = address else {
186+
return;
187+
};
188+
189+
if let Some(tcp_bind_address) = addresses.tcp_bind_address() {
190+
buf.push(NetAddress {
191+
name: P::NAME.to_owned(),
192+
address: tcp_bind_address.to_string(),
193+
kind: NetAddressKind::Tcp,
194+
});
195+
}
196+
197+
if let Some(uds_path) = addresses.uds_path() {
198+
buf.push(NetAddress {
199+
name: P::NAME.to_owned(),
200+
address: uds_path.display().to_string(),
201+
kind: NetAddressKind::Unix,
202+
});
203+
}
204+
}
205+
206+
#[inline(always)]
207+
fn push_advertised<P: ListenerPort + 'static>(
208+
address: AdvertisedAddress<P>,
209+
buf: &mut Vec<NetAddress>,
210+
) {
211+
let Ok(address) = address.into_address() else {
212+
return;
213+
};
214+
215+
buf.push(NetAddress {
216+
kind: match &address {
217+
PeerNetAddress::Uds(..) => NetAddressKind::Unix,
218+
PeerNetAddress::Http(..) => NetAddressKind::Http,
219+
},
220+
name: P::NAME.to_owned(),
221+
address: address.to_string(),
222+
})
223+
}

crates/types/src/net/listener.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,22 @@ impl Drop for ListenersErased {
383383
}
384384
}
385385

386-
#[allow(dead_code)]
387386
pub struct Addresses<P: ListenerPort> {
388387
tcp_bind_address: Option<SocketAddr>,
389388
uds_path: Option<PathBuf>,
390389
_phantom: std::marker::PhantomData<P>,
391390
}
392391

392+
impl<P: ListenerPort + 'static> Addresses<P> {
393+
pub fn tcp_bind_address(&self) -> Option<SocketAddr> {
394+
self.tcp_bind_address
395+
}
396+
397+
pub fn uds_path(&self) -> Option<&PathBuf> {
398+
self.uds_path.as_ref()
399+
}
400+
}
401+
393402
#[derive(Default)]
394403
pub struct Listeners<P: ListenerPort> {
395404
tcp_listener: Option<TcpListener>,

0 commit comments

Comments
 (0)