1use async_trait::async_trait;
2use std::collections::HashMap;
3
4use crate::errors::Result;
5use crate::request::{get, put};
6use crate::Client;
7
8#[derive(Clone, Default, Eq, PartialEq, Serialize, Deserialize, Debug)]
9#[serde(default)]
10pub struct AgentCheck {
11 pub Node: String,
12 pub CheckID: String,
13 pub Name: String,
14 pub Status: String,
15 pub Notes: String,
16 pub Output: String,
17 pub ServiceID: String,
18 pub ServiceName: String,
19}
20
21#[derive(Clone, Default, Eq, PartialEq, Serialize, Deserialize, Debug)]
22#[serde(default)]
23pub struct AgentMember {
24 pub Name: String,
25 pub Addr: String,
26 pub Port: u16,
27 pub Tags: HashMap<String, String>,
28 pub pubStatus: usize,
29 pub ProtocolMin: u8,
30 pub ProtocolMax: u8,
31 pub ProtocolCur: u8,
32 pub DelegateMin: u8,
33 pub DelegateMax: u8,
34 pub DelegateCur: u8,
35}
36
37#[derive(Eq, Default, PartialEq, Serialize, Deserialize, Debug, Clone)]
38#[serde(default)]
39pub struct AgentService {
40 pub ID: String,
41 pub Service: String,
42 pub Tags: Option<Vec<String>>,
43 pub Port: u16,
44 pub Address: String,
45 pub EnableTagOverride: bool,
46 pub CreateIndex: u64,
47 pub ModifyIndex: u64,
48}
49
50#[async_trait]
53pub trait Agent {
54 async fn checks(&self) -> Result<HashMap<String, AgentCheck>>;
55 async fn members(&self, wan: bool) -> Result<AgentMember>;
56 async fn reload(&self) -> Result<()>;
57 async fn maintenance_mode(&self, enable: bool, reason: Option<&str>) -> Result<()>;
58 async fn join(&self, address: &str, wan: bool) -> Result<()>;
59 async fn leave(&self) -> Result<()>;
60 async fn force_leave(&self) -> Result<()>;
61}
62
63#[async_trait]
64impl Agent for Client {
65 async fn checks(&self) -> Result<HashMap<String, AgentCheck>> {
67 get("/v1/agent/checks", &self.config, HashMap::new(), None)
68 .await
69 .map(|x| x.0)
70 }
71 async fn members(&self, wan: bool) -> Result<AgentMember> {
73 let mut params = HashMap::new();
74 if wan {
75 params.insert(String::from("wan"), String::from("1"));
76 }
77 get("/v1/agent/members", &self.config, params, None)
78 .await
79 .map(|x| x.0)
80 }
81 async fn reload(&self) -> Result<()> {
83 put(
84 "/v1/agent/reload",
85 None as Option<&()>,
86 &self.config,
87 HashMap::new(),
88 None,
89 )
90 .await
91 .map(|x| x.0)
92 }
93
94 async fn maintenance_mode(&self, enable: bool, reason: Option<&str>) -> Result<()> {
96 let mut params = HashMap::new();
97 let enable_str = if enable {
98 String::from("true")
99 } else {
100 String::from("false")
101 };
102 params.insert(String::from("enabled"), enable_str);
103 if let Some(r) = reason {
104 params.insert(String::from("reason"), r.to_owned());
105 }
106 put(
107 "/v1/agent/maintenance",
108 None as Option<&()>,
109 &self.config,
110 params,
111 None,
112 )
113 .await
114 .map(|x| x.0)
115 }
116
117 async fn join(&self, address: &str, wan: bool) -> Result<()> {
119 let mut params = HashMap::new();
120
121 if wan {
122 params.insert(String::from("wan"), String::from("true"));
123 }
124 let path = format!("/v1/agent/join/{}", address);
125 put(&path, None as Option<&()>, &self.config, params, None)
126 .await
127 .map(|x| x.0)
128 }
129
130 async fn leave(&self) -> Result<()> {
132 put(
133 "/v1/agent/leave",
134 None as Option<&()>,
135 &self.config,
136 HashMap::new(),
137 None,
138 )
139 .await
140 .map(|x| x.0)
141 }
142
143 async fn force_leave(&self) -> Result<()> {
145 put(
146 "/v1/agent/force-leave",
147 None as Option<&()>,
148 &self.config,
149 HashMap::new(),
150 None,
151 )
152 .await
153 .map(|x| x.0)
154 }
155}