(spec: &str)
| 292 | } |
| 293 | |
| 294 | fn parse_add_endpoint_spec(spec: &str) -> Result<NetworkEndpoint> { |
| 295 | let parts = spec.split(':').collect::<Vec<_>>(); |
| 296 | if !(2..=6).contains(&parts.len()) { |
| 297 | return Err(miette!( |
| 298 | "--add-endpoint expects host:port[:access[:protocol[:enforcement[:options]]]], got '{spec}'" |
| 299 | )); |
| 300 | } |
| 301 | |
| 302 | let host = parse_host("--add-endpoint", spec, parts[0])?; |
| 303 | let port = parse_port("--add-endpoint", spec, parts[1])?; |
| 304 | |
| 305 | let access = parts.get(2).copied().unwrap_or("").trim(); |
| 306 | let protocol = parts.get(3).copied().unwrap_or("").trim(); |
| 307 | let enforcement = parts.get(4).copied().unwrap_or("").trim(); |
| 308 | let options = parts.get(5).copied().unwrap_or("").trim(); |
| 309 | |
| 310 | if parts.len() == 3 && access.is_empty() { |
| 311 | return Err(miette!( |
| 312 | "--add-endpoint has an empty access segment in '{spec}'; omit it entirely if you do not need access or protocol fields" |
| 313 | )); |
| 314 | } |
| 315 | if parts.len() == 6 && options.is_empty() { |
| 316 | return Err(miette!( |
| 317 | "--add-endpoint has an empty options segment in '{spec}'; omit it entirely if you do not need endpoint options" |
| 318 | )); |
| 319 | } |
| 320 | if !enforcement.is_empty() && protocol.is_empty() { |
| 321 | return Err(miette!( |
| 322 | "--add-endpoint cannot set enforcement without protocol in '{spec}'" |
| 323 | )); |
| 324 | } |
| 325 | if !access.is_empty() && !matches!(access, "read-only" | "read-write" | "full") { |
| 326 | return Err(miette!( |
| 327 | "--add-endpoint access segment must be one of read-only, read-write, or full; got '{access}' in '{spec}'" |
| 328 | )); |
| 329 | } |
| 330 | if !protocol.is_empty() && !matches!(protocol, "rest" | "websocket" | "sql") { |
| 331 | return Err(miette!( |
| 332 | "--add-endpoint protocol segment must be 'rest', 'websocket', or 'sql'; got '{protocol}' in '{spec}'" |
| 333 | )); |
| 334 | } |
| 335 | if !enforcement.is_empty() && !matches!(enforcement, "enforce" | "audit") { |
| 336 | return Err(miette!( |
| 337 | "--add-endpoint enforcement segment must be 'enforce' or 'audit'; got '{enforcement}' in '{spec}'" |
| 338 | )); |
| 339 | } |
| 340 | |
| 341 | let mut endpoint = NetworkEndpoint { |
| 342 | host, |
| 343 | port, |
| 344 | ports: vec![port], |
| 345 | protocol: protocol.to_string(), |
| 346 | enforcement: enforcement.to_string(), |
| 347 | access: access.to_string(), |
| 348 | ..Default::default() |
| 349 | }; |
| 350 | apply_add_endpoint_options(spec, &mut endpoint, options)?; |
| 351 | Ok(endpoint) |
no test coverage detected