use std::collections::HashMap; use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use crate::config::RuntimeConfigConsul; #[derive(Serialize, Deserialize, Debug)] pub struct ServiceEntry { pub Tags: Vec, } #[derive(Serialize, Deserialize, Debug)] pub struct CatalogNode { pub Services: HashMap, } pub struct Consul { client: reqwest::Client, url: String, idx: Option, } impl Consul { pub fn new(config: &RuntimeConfigConsul) -> Self { let client = if let Some((ca, ident)) = config.tls.clone() { reqwest::Client::builder() .use_rustls_tls() .add_root_certificate(ca) .identity(ident) .build() .expect("Unable to build reqwest client") } else { reqwest::Client::new() }; return Self { client, url: config.url.clone(), idx: None, }; } pub fn watch_node_reset(&mut self) -> () { self.idx = None; } pub async fn watch_node(&mut self, host: &str) -> Result { let url = match self.idx { Some(i) => format!("{}/v1/catalog/node/{}?index={}", self.url, host, i), None => format!("{}/v1/catalog/node/{}", self.url, host), }; let http = self.client.get(&url).send().await?; self.idx = match http.headers().get("X-Consul-Index") { Some(v) => Some(v.to_str()?.parse::()?), None => return Err(anyhow!("X-Consul-Index header not found")), }; let resp: CatalogNode = http.json().await?; return Ok(resp); } }