aboutsummaryrefslogtreecommitdiff
path: root/src/consul.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/consul.rs')
-rw-r--r--src/consul.rs62
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);
+ }
+}