diff options
Diffstat (limited to 'src/consul.rs')
-rw-r--r-- | src/consul.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/consul.rs b/src/consul.rs new file mode 100644 index 0000000..81074f4 --- /dev/null +++ b/src/consul.rs @@ -0,0 +1,62 @@ +use std::collections::HashMap; + +use anyhow::Result; +use log::*; +use serde::{Deserialize, Serialize}; + +// ---- Watch and retrieve Consul catalog ---- + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConsulServiceEntry { + #[serde(rename = "Address")] + pub address: String, + + #[serde(rename = "Port")] + pub port: u16, + + #[serde(rename = "Tags")] + pub tags: Vec<String>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConsulNodeCatalog { + #[serde(rename = "Services")] + pub services: HashMap<String, ConsulServiceEntry>, +} + +#[derive(Clone)] +pub struct Consul { + client: reqwest::Client, + url: String, + idx: Option<u64>, +} + +impl Consul { + pub fn new(url: &str) -> Self { + return Self { + client: reqwest::Client::new(), + url: url.to_string(), + idx: None, + }; + } + + pub fn watch_node_reset(&mut self) -> () { + self.idx = None; + } + + pub async fn watch_node(&mut self, host: &str) -> Result<ConsulNodeCatalog> { + 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::<u64>()?), + None => return Err(anyhow!("X-Consul-Index header not found")), + }; + + let resp: ConsulNodeCatalog = http.json().await?; + return Ok(resp); + } +} |