datadog_agent_commons/ipc/
config.rs1use std::path::{Path, PathBuf};
4
5use tonic::transport::Uri;
6
7use crate::platform::PlatformSettings;
8
9#[derive(Clone, Debug)]
11pub struct IpcAuthConfiguration {
12 auth_token_file_path: PathBuf,
19
20 ipc_cert_file_path: PathBuf,
29}
30
31impl IpcAuthConfiguration {
32 pub fn new(mut auth_token_file_path: PathBuf, mut ipc_cert_file_path: PathBuf) -> Self {
37 if auth_token_file_path.as_os_str().is_empty() {
38 auth_token_file_path = PlatformSettings::get_auth_token_path();
39 }
40
41 if ipc_cert_file_path.as_os_str().is_empty() {
42 let auth_token_dir = auth_token_file_path
43 .parent()
44 .unwrap_or(PlatformSettings::get_config_dir_path());
45 ipc_cert_file_path = auth_token_dir.join(PlatformSettings::get_ipc_cert_filename());
46 }
47
48 Self {
49 auth_token_file_path,
50 ipc_cert_file_path,
51 }
52 }
53
54 pub fn auth_token_file_path(&self) -> &Path {
56 &self.auth_token_file_path
57 }
58
59 pub fn ipc_cert_file_path(&self) -> &Path {
61 &self.ipc_cert_file_path
62 }
63}
64
65#[derive(Clone, Debug)]
67pub struct RemoteAgentClientConfiguration {
68 pub cmd_port: u16,
70
71 pub auth: IpcAuthConfiguration,
73
74 pub grpc_max_message_size: usize,
76
77 #[cfg(target_os = "linux")]
79 pub vsock_cid: Option<u32>,
80}
81
82impl RemoteAgentClientConfiguration {
83 pub fn endpoint(&self) -> Uri {
85 format!("https://127.0.0.1:{}", self.cmd_port)
86 .parse()
87 .expect("a URI built from a u16 port is valid")
88 }
89
90 #[cfg(target_os = "linux")]
92 pub fn vsock_addr(&self) -> Option<tokio_vsock::VsockAddr> {
93 self.vsock_cid
94 .map(|cid| tokio_vsock::VsockAddr::new(cid, u32::from(self.cmd_port)))
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use std::path::{Path, PathBuf};
101
102 use super::{IpcAuthConfiguration, RemoteAgentClientConfiguration};
103 use crate::platform::PlatformSettings;
104
105 #[test]
106 fn ipc_cert_file_path_empty_config() {
107 let default_auth_token_path = PlatformSettings::get_auth_token_path();
108
109 let config = IpcAuthConfiguration::new(PathBuf::new(), PathBuf::new());
112 assert_eq!(config.auth_token_file_path(), default_auth_token_path);
113 assert_eq!(
114 config.ipc_cert_file_path().parent(),
115 default_auth_token_path.as_path().parent()
116 );
117 assert_eq!(
118 config.ipc_cert_file_path().file_name().map(Path::new),
119 Some(PlatformSettings::get_ipc_cert_filename())
120 );
121 }
122
123 #[test]
124 fn ipc_cert_file_path_defaults() {
125 let default_auth_token_path = PlatformSettings::get_auth_token_path();
126
127 let config = IpcAuthConfiguration::new(default_auth_token_path.clone(), PathBuf::new());
130 assert_eq!(
131 config.ipc_cert_file_path().parent(),
132 default_auth_token_path.as_path().parent()
133 );
134 assert_eq!(
135 config.ipc_cert_file_path().file_name().map(Path::new),
136 Some(PlatformSettings::get_ipc_cert_filename())
137 );
138 }
139
140 #[test]
141 fn ipc_cert_file_path_explicitly_set() {
142 let default_auth_token_path = PlatformSettings::get_auth_token_path();
143 let custom_ipc_cert_path = PathBuf::from("/tmp/custom_ipc_cert.pem");
144
145 let config = IpcAuthConfiguration::new(default_auth_token_path, custom_ipc_cert_path.clone());
147 assert_eq!(custom_ipc_cert_path, config.ipc_cert_file_path());
148 }
149
150 #[test]
151 fn ipc_cert_file_path_custom_auth_token_path() {
152 let custom_auth_token_path = PathBuf::from("/secret/auth_token");
153
154 let config = IpcAuthConfiguration::new(custom_auth_token_path.clone(), PathBuf::new());
157 assert_eq!(
158 config.ipc_cert_file_path().parent(),
159 custom_auth_token_path.as_path().parent()
160 );
161 assert_eq!(
162 config.ipc_cert_file_path().file_name().map(Path::new),
163 Some(PlatformSettings::get_ipc_cert_filename())
164 );
165 }
166
167 #[test]
168 fn ipc_cert_file_path_invalid_auth_token_path() {
169 let invalid_auth_token_path = PathBuf::from("/");
170
171 let config = IpcAuthConfiguration::new(invalid_auth_token_path, PathBuf::new());
174 assert_eq!(
175 config.ipc_cert_file_path().parent(),
176 Some(PlatformSettings::get_config_dir_path())
177 );
178 assert_eq!(
179 config.ipc_cert_file_path().file_name().map(Path::new),
180 Some(PlatformSettings::get_ipc_cert_filename())
181 );
182 }
183
184 fn remote_agent_config(cmd_port: u16) -> RemoteAgentClientConfiguration {
185 RemoteAgentClientConfiguration {
186 cmd_port,
187 auth: IpcAuthConfiguration::new(PathBuf::new(), PathBuf::new()),
188 grpc_max_message_size: 128 * 1024 * 1024,
189 #[cfg(target_os = "linux")]
190 vsock_cid: None,
191 }
192 }
193
194 #[test]
195 fn endpoint_uses_cmd_port() {
196 for (cmd_port, expected) in [(5001, "https://127.0.0.1:5001/"), (7777, "https://127.0.0.1:7777/")] {
197 assert_eq!(remote_agent_config(cmd_port).endpoint().to_string(), expected);
198 }
199 }
200
201 #[cfg(target_os = "linux")]
202 #[test]
203 fn vsock_addr_uses_resolved_cid_and_cmd_port() {
204 let mut config = remote_agent_config(5001);
205 assert_eq!(config.vsock_addr(), None);
206
207 config.vsock_cid = Some(2);
208 let addr = config.vsock_addr().expect("vsock address should be configured");
209 assert_eq!(addr.cid(), 2);
210 assert_eq!(addr.port(), 5001);
211 }
212}