1use serde::{Deserialize, Serialize};
3use serde_json::{Map, Value, json};
4
5use super::{Fleet, FleetPage, Item};
6use crate::{Scope, http::Method, pagination::paginated, request::endpoint};
7
8#[derive(Clone, Debug, Deserialize, Serialize)]
9#[non_exhaustive]
10pub struct Agent {
11 pub id: String,
12 #[serde(default)]
13 pub policy_id: Option<String>,
14 #[serde(default, skip_serializing_if = "Option::is_none")]
17 pub policy_revision: Option<u64>,
18 #[serde(default)]
19 pub active: Option<bool>,
20 #[serde(default)]
21 pub status: Option<String>,
22 #[serde(default)]
23 pub local_metadata: Value,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub last_checkin: Option<String>,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub tags: Option<Vec<String>>,
28 #[serde(flatten)]
29 pub extra: Map<String, Value>,
30}
31
32#[derive(Clone, Debug, Serialize)]
34#[serde(untagged)]
35pub enum AgentSelection {
36 Ids(Vec<String>),
37 Query(String),
38}
39
40#[derive(Clone, Debug, Deserialize, Serialize)]
43#[serde(untagged)]
44#[non_exhaustive]
45pub enum BulkActionResult {
46 Action {
47 #[serde(rename = "actionId")]
48 action_id: String,
49 },
50 DryRun { count: u64 },
52}
53
54#[derive(Clone, Copy, Debug, Serialize)]
55#[non_exhaustive]
56pub enum DiagnosticMetric {
57 #[serde(rename = "CPU")]
58 Cpu,
59}
60
61impl<'a> Fleet<'a> {
62 pub fn find_agents(&self) -> FindAgents<'a> {
63 FindAgents(
64 self.0
65 .request(Method::GET, Scope::Space, &["api", "fleet", "agents"]),
66 )
67 }
68
69 pub fn get_agent(&self, id: &str) -> GetAgent<'a> {
70 GetAgent(
71 self.0
72 .request(Method::GET, Scope::Space, &["api", "fleet", "agents", id]),
73 )
74 }
75
76 pub fn agent_status(&self) -> AgentStatus<'a> {
78 AgentStatus(
79 self.0
80 .request(Method::GET, Scope::Space, &["api", "fleet", "agent_status"]),
81 )
82 }
83
84 pub fn reassign_agent(&self, id: &str, policy_id: &str) -> ReassignAgent<'a> {
85 ReassignAgent(
86 self.0
87 .request(
88 Method::POST,
89 Scope::Space,
90 &["api", "fleet", "agents", id, "reassign"],
91 )
92 .nonempty("policy_id", policy_id)
93 .field("policy_id", policy_id),
94 )
95 }
96
97 pub fn unenroll_agent(&self, id: &str) -> UnenrollAgent<'a> {
98 UnenrollAgent(
99 self.0
100 .request(
101 Method::POST,
102 Scope::Space,
103 &["api", "fleet", "agents", id, "unenroll"],
104 )
105 .json(&json!({})),
106 )
107 }
108
109 pub fn upgrade_agent(&self, id: &str, version: &str) -> UpgradeAgent<'a> {
112 UpgradeAgent(
113 self.0
114 .request(
115 Method::POST,
116 Scope::Space,
117 &["api", "fleet", "agents", id, "upgrade"],
118 )
119 .nonempty("version", version)
120 .field("version", version),
121 )
122 }
123
124 pub fn request_agent_diagnostics(&self, id: &str) -> RequestAgentDiagnostics<'a> {
127 RequestAgentDiagnostics(
128 self.0
129 .request(
130 Method::POST,
131 Scope::Space,
132 &["api", "fleet", "agents", id, "request_diagnostics"],
133 )
134 .json(&json!({})),
135 )
136 }
137
138 pub fn bulk_reassign_agents(
139 &self,
140 agents: AgentSelection,
141 policy_id: &str,
142 ) -> BulkReassignAgents<'a> {
143 BulkReassignAgents(
144 self.0
145 .request(
146 Method::POST,
147 Scope::Space,
148 &["api", "fleet", "agents", "bulk_reassign"],
149 )
150 .field("agents", agents)
151 .nonempty("policy_id", policy_id)
152 .field("policy_id", policy_id),
153 )
154 }
155
156 pub fn bulk_unenroll_agents(&self, agents: AgentSelection) -> BulkUnenrollAgents<'a> {
157 BulkUnenrollAgents(
158 self.0
159 .request(
160 Method::POST,
161 Scope::Space,
162 &["api", "fleet", "agents", "bulk_unenroll"],
163 )
164 .field("agents", agents),
165 )
166 }
167
168 pub fn bulk_update_agent_tags(&self, agents: AgentSelection) -> BulkUpdateAgentTags<'a> {
169 BulkUpdateAgentTags(
170 self.0
171 .request(
172 Method::POST,
173 Scope::Space,
174 &["api", "fleet", "agents", "bulk_update_agent_tags"],
175 )
176 .field("agents", agents),
177 )
178 }
179
180 pub fn bulk_upgrade_agents(
181 &self,
182 agents: AgentSelection,
183 version: &str,
184 ) -> BulkUpgradeAgents<'a> {
185 BulkUpgradeAgents(
186 self.0
187 .request(
188 Method::POST,
189 Scope::Space,
190 &["api", "fleet", "agents", "bulk_upgrade"],
191 )
192 .field("agents", agents)
193 .nonempty("version", version)
194 .field("version", version),
195 )
196 }
197
198 pub fn bulk_request_agent_diagnostics(
199 &self,
200 agents: AgentSelection,
201 ) -> BulkRequestAgentDiagnostics<'a> {
202 BulkRequestAgentDiagnostics(
203 self.0
204 .request(
205 Method::POST,
206 Scope::Space,
207 &["api", "fleet", "agents", "bulk_request_diagnostics"],
208 )
209 .field("agents", agents),
210 )
211 }
212}
213
214macro_rules! bulk_setters {
215 ($($name:ident),*) => {$(
216 impl $name<'_> {
217 pub fn dry_run(self, dry_run: bool) -> Self {
220 Self(self.0.field("dryRun", dry_run))
221 }
222
223 pub fn batch_size(self, size: u32) -> Self {
227 Self(self.0.field("batchSize", size))
228 }
229 }
230 )*};
231}
232
233macro_rules! include_inactive_setter {
234 ($($name:ident),*) => {$(
235 impl $name<'_> {
236 pub fn include_inactive(self, include: bool) -> Self {
238 Self(self.0.field("includeInactive", include))
239 }
240 }
241 )*};
242}
243
244macro_rules! upgrade_setters {
245 ($($name:ident),*) => {$(
246 impl $name<'_> {
247 pub fn force(self, force: bool) -> Self {
249 Self(self.0.field("force", force))
250 }
251
252 pub fn source_uri(self, uri: &str) -> Self {
254 Self(self.0.field("source_uri", uri))
255 }
256
257 pub fn skip_rate_limit_check(self, skip: bool) -> Self {
258 Self(self.0.field("skipRateLimitCheck", skip))
259 }
260 }
261 )*};
262}
263
264macro_rules! diagnostics_setters {
265 ($($name:ident),*) => {$(
266 impl $name<'_> {
267 pub fn additional_metrics(self, metrics: Vec<DiagnosticMetric>) -> Self {
268 Self(self.0.field("additional_metrics", metrics))
269 }
270 }
271 )*};
272}
273
274endpoint! {
275 FindAgents => FleetPage<Agent>
277}
278
279impl FindAgents<'_> {
280 pub fn show_inactive(self, show: bool) -> Self {
281 Self(self.0.param("showInactive", show))
282 }
283}
284
285endpoint! {
286 GetAgent => Item<Agent>
288}
289
290endpoint! {
291 AgentStatus => Value
293}
294
295impl AgentStatus<'_> {
296 pub fn policy_id(self, id: &str) -> Self {
297 Self(self.0.param("policyId", id))
298 }
299
300 pub fn kuery(self, kuery: &str) -> Self {
301 Self(self.0.param("kuery", kuery))
302 }
303}
304
305endpoint! {
306 ReassignAgent => Value
308}
309
310endpoint! {
311 UnenrollAgent => Value
313}
314
315impl UnenrollAgent<'_> {
316 pub fn force(self, force: bool) -> Self {
318 Self(self.0.field("force", force))
319 }
320
321 pub fn revoke(self, revoke: bool) -> Self {
323 Self(self.0.field("revoke", revoke))
324 }
325}
326
327endpoint! {
328 UpgradeAgent => Value
330}
331
332endpoint! {
333 RequestAgentDiagnostics => BulkActionResult
335}
336
337endpoint! {
338 BulkReassignAgents => BulkActionResult
340}
341
342endpoint! {
343 BulkUnenrollAgents => BulkActionResult
345}
346
347impl BulkUnenrollAgents<'_> {
348 pub fn force(self, force: bool) -> Self {
350 Self(self.0.field("force", force))
351 }
352
353 pub fn revoke(self, revoke: bool) -> Self {
355 Self(self.0.field("revoke", revoke))
356 }
357}
358
359endpoint! {
360 BulkUpdateAgentTags => BulkActionResult
362}
363
364impl BulkUpdateAgentTags<'_> {
365 pub fn add_tags<I: IntoIterator<Item = S>, S: Into<String>>(self, tags: I) -> Self {
366 let tags: Vec<String> = tags.into_iter().map(Into::into).collect();
367 Self(self.0.field("tagsToAdd", tags))
368 }
369
370 pub fn remove_tags<I: IntoIterator<Item = S>, S: Into<String>>(self, tags: I) -> Self {
371 let tags: Vec<String> = tags.into_iter().map(Into::into).collect();
372 Self(self.0.field("tagsToRemove", tags))
373 }
374}
375
376endpoint! {
377 BulkUpgradeAgents => BulkActionResult
379}
380
381impl BulkUpgradeAgents<'_> {
382 pub fn start_time(self, time: &str) -> Self {
384 Self(self.0.field("start_time", time))
385 }
386
387 pub fn rollout_duration_seconds(self, seconds: u64) -> Self {
389 Self(self.0.field("rollout_duration_seconds", seconds))
390 }
391}
392
393endpoint! {
394 BulkRequestAgentDiagnostics => BulkActionResult
396}
397
398page_setters!(FindAgents);
399sort_setters!(FindAgents);
400bulk_setters!(
401 BulkReassignAgents,
402 BulkUnenrollAgents,
403 BulkUpdateAgentTags,
404 BulkUpgradeAgents,
405 BulkRequestAgentDiagnostics
406);
407include_inactive_setter!(
408 BulkReassignAgents,
409 BulkUnenrollAgents,
410 BulkUpdateAgentTags,
411 BulkUpgradeAgents
412);
413upgrade_setters!(UpgradeAgent, BulkUpgradeAgents);
414diagnostics_setters!(RequestAgentDiagnostics, BulkRequestAgentDiagnostics);
415paginated!(FindAgents => FleetPage<Agent>);