Skip to main content

hanzo_client/apis/
visor_api.rs

1/*
2 * Hanzo Cloud API
3 *
4 * The Hanzo Cloud API as a customer calls it: every operation under /v1/ except the operator's admin product, relay routes, legacy spellings and capabilities still reached by flag. Tagged by product: the first path segment after /v1/.
5 *
6 * The version of the OpenAPI document: v1
7 * 
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`attach_cluster`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum AttachClusterError {
22    UnknownValue(serde_json::Value),
23}
24
25/// struct for typed errors of method [`bind_machine_agent`]
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(untagged)]
28pub enum BindMachineAgentError {
29    UnknownValue(serde_json::Value),
30}
31
32/// struct for typed errors of method [`cancel_fleet_job`]
33#[derive(Debug, Clone, Serialize, Deserialize)]
34#[serde(untagged)]
35pub enum CancelFleetJobError {
36    UnknownValue(serde_json::Value),
37}
38
39/// struct for typed errors of method [`create_kubernetes_cluster`]
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(untagged)]
42pub enum CreateKubernetesClusterError {
43    UnknownValue(serde_json::Value),
44}
45
46/// struct for typed errors of method [`create_node_pool`]
47#[derive(Debug, Clone, Serialize, Deserialize)]
48#[serde(untagged)]
49pub enum CreateNodePoolError {
50    UnknownValue(serde_json::Value),
51}
52
53/// struct for typed errors of method [`delete_bot`]
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(untagged)]
56pub enum DeleteBotError {
57    UnknownValue(serde_json::Value),
58}
59
60/// struct for typed errors of method [`delete_kubernetes_cluster`]
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(untagged)]
63pub enum DeleteKubernetesClusterError {
64    UnknownValue(serde_json::Value),
65}
66
67/// struct for typed errors of method [`delete_machine`]
68#[derive(Debug, Clone, Serialize, Deserialize)]
69#[serde(untagged)]
70pub enum DeleteMachineError {
71    UnknownValue(serde_json::Value),
72}
73
74/// struct for typed errors of method [`delete_node_pool`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum DeleteNodePoolError {
78    UnknownValue(serde_json::Value),
79}
80
81/// struct for typed errors of method [`detach_cluster`]
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(untagged)]
84pub enum DetachClusterError {
85    UnknownValue(serde_json::Value),
86}
87
88/// struct for typed errors of method [`get_bot`]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90#[serde(untagged)]
91pub enum GetBotError {
92    UnknownValue(serde_json::Value),
93}
94
95/// struct for typed errors of method [`get_kubernetes_cluster`]
96#[derive(Debug, Clone, Serialize, Deserialize)]
97#[serde(untagged)]
98pub enum GetKubernetesClusterError {
99    UnknownValue(serde_json::Value),
100}
101
102/// struct for typed errors of method [`get_machine`]
103#[derive(Debug, Clone, Serialize, Deserialize)]
104#[serde(untagged)]
105pub enum GetMachineError {
106    UnknownValue(serde_json::Value),
107}
108
109/// struct for typed errors of method [`get_machine_agent`]
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(untagged)]
112pub enum GetMachineAgentError {
113    UnknownValue(serde_json::Value),
114}
115
116/// struct for typed errors of method [`get_visor_compute_regions`]
117#[derive(Debug, Clone, Serialize, Deserialize)]
118#[serde(untagged)]
119pub enum GetVisorComputeRegionsError {
120    UnknownValue(serde_json::Value),
121}
122
123/// struct for typed errors of method [`get_visor_compute_sizes`]
124#[derive(Debug, Clone, Serialize, Deserialize)]
125#[serde(untagged)]
126pub enum GetVisorComputeSizesError {
127    UnknownValue(serde_json::Value),
128}
129
130/// struct for typed errors of method [`list_bots`]
131#[derive(Debug, Clone, Serialize, Deserialize)]
132#[serde(untagged)]
133pub enum ListBotsError {
134    UnknownValue(serde_json::Value),
135}
136
137/// struct for typed errors of method [`list_clusters`]
138#[derive(Debug, Clone, Serialize, Deserialize)]
139#[serde(untagged)]
140pub enum ListClustersError {
141    UnknownValue(serde_json::Value),
142}
143
144/// struct for typed errors of method [`list_fleet`]
145#[derive(Debug, Clone, Serialize, Deserialize)]
146#[serde(untagged)]
147pub enum ListFleetError {
148    UnknownValue(serde_json::Value),
149}
150
151/// struct for typed errors of method [`list_fleet_jobs`]
152#[derive(Debug, Clone, Serialize, Deserialize)]
153#[serde(untagged)]
154pub enum ListFleetJobsError {
155    UnknownValue(serde_json::Value),
156}
157
158/// struct for typed errors of method [`list_fleet_samples`]
159#[derive(Debug, Clone, Serialize, Deserialize)]
160#[serde(untagged)]
161pub enum ListFleetSamplesError {
162    UnknownValue(serde_json::Value),
163}
164
165/// struct for typed errors of method [`list_fleet_workers`]
166#[derive(Debug, Clone, Serialize, Deserialize)]
167#[serde(untagged)]
168pub enum ListFleetWorkersError {
169    UnknownValue(serde_json::Value),
170}
171
172/// struct for typed errors of method [`list_gpu_alerts`]
173#[derive(Debug, Clone, Serialize, Deserialize)]
174#[serde(untagged)]
175pub enum ListGpuAlertsError {
176    UnknownValue(serde_json::Value),
177}
178
179/// struct for typed errors of method [`list_gpus`]
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(untagged)]
182pub enum ListGpusError {
183    UnknownValue(serde_json::Value),
184}
185
186/// struct for typed errors of method [`list_kubernetes_clusters`]
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(untagged)]
189pub enum ListKubernetesClustersError {
190    UnknownValue(serde_json::Value),
191}
192
193/// struct for typed errors of method [`list_kubernetes_nodes`]
194#[derive(Debug, Clone, Serialize, Deserialize)]
195#[serde(untagged)]
196pub enum ListKubernetesNodesError {
197    UnknownValue(serde_json::Value),
198}
199
200/// struct for typed errors of method [`list_machine_agents`]
201#[derive(Debug, Clone, Serialize, Deserialize)]
202#[serde(untagged)]
203pub enum ListMachineAgentsError {
204    UnknownValue(serde_json::Value),
205}
206
207/// struct for typed errors of method [`list_machines`]
208#[derive(Debug, Clone, Serialize, Deserialize)]
209#[serde(untagged)]
210pub enum ListMachinesError {
211    UnknownValue(serde_json::Value),
212}
213
214/// struct for typed errors of method [`post_visor_compute_bots_by_id_by_action`]
215#[derive(Debug, Clone, Serialize, Deserialize)]
216#[serde(untagged)]
217pub enum PostVisorComputeBotsByIdByActionError {
218    UnknownValue(serde_json::Value),
219}
220
221/// struct for typed errors of method [`post_visor_compute_bots_launch`]
222#[derive(Debug, Clone, Serialize, Deserialize)]
223#[serde(untagged)]
224pub enum PostVisorComputeBotsLaunchError {
225    UnknownValue(serde_json::Value),
226}
227
228/// struct for typed errors of method [`post_visor_machines`]
229#[derive(Debug, Clone, Serialize, Deserialize)]
230#[serde(untagged)]
231pub enum PostVisorMachinesError {
232    UnknownValue(serde_json::Value),
233}
234
235/// struct for typed errors of method [`record_fleet_sample`]
236#[derive(Debug, Clone, Serialize, Deserialize)]
237#[serde(untagged)]
238pub enum RecordFleetSampleError {
239    UnknownValue(serde_json::Value),
240}
241
242/// struct for typed errors of method [`scale_node_pool`]
243#[derive(Debug, Clone, Serialize, Deserialize)]
244#[serde(untagged)]
245pub enum ScaleNodePoolError {
246    UnknownValue(serde_json::Value),
247}
248
249/// struct for typed errors of method [`unbind_machine_agent`]
250#[derive(Debug, Clone, Serialize, Deserialize)]
251#[serde(untagged)]
252pub enum UnbindMachineAgentError {
253    UnknownValue(serde_json::Value),
254}
255
256
257/// Attaches a BYO cluster to the caller's org — the kubeconfig is validated, KMS-sealed and added to the fleet — and answers 201 with the cluster as it now appears on GET /v1/visor/clusters. Billed the nominal management fee: the customer brings the compute, Hanzo meters the management plane.
258pub async fn attach_cluster(configuration: &configuration::Configuration, cluster_attach: models::ClusterAttach) -> Result<models::ClusterView, Error<AttachClusterError>> {
259    // add a prefix to parameters to efficiently prevent name collisions
260    let p_cluster_attach = cluster_attach;
261
262    let uri_str = format!("{}/v1/visor/clusters", configuration.base_path);
263    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
264
265    if let Some(ref user_agent) = configuration.user_agent {
266        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
267    }
268    if let Some(ref token) = configuration.bearer_access_token {
269        req_builder = req_builder.bearer_auth(token.to_owned());
270    };
271    req_builder = req_builder.json(&p_cluster_attach);
272
273    let req = req_builder.build()?;
274    let resp = configuration.client.execute(req).await?;
275
276    let status = resp.status();
277    let content_type = resp
278        .headers()
279        .get("content-type")
280        .and_then(|v| v.to_str().ok())
281        .unwrap_or("application/octet-stream");
282    let content_type = super::ContentType::from(content_type);
283
284    if !status.is_client_error() && !status.is_server_error() {
285        let content = resp.text().await?;
286        match content_type {
287            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
288            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterView`"))),
289            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterView`")))),
290        }
291    } else {
292        let content = resp.text().await?;
293        let entity: Option<AttachClusterError> = serde_json::from_str(&content).ok();
294        Err(Error::ResponseError(ResponseContent { status, content, entity }))
295    }
296}
297
298/// Binds a cloud Agent to one of the caller org's machines: the machine is recorded as running that Agent's @hanzo/bot runtime. The owning org is the validated tenant, never a client field.
299pub async fn bind_machine_agent(configuration: &configuration::Configuration, id: &str, bind_agent_req: models::BindAgentReq) -> Result<models::AgentBinding, Error<BindMachineAgentError>> {
300    // add a prefix to parameters to efficiently prevent name collisions
301    let p_id = id;
302    let p_bind_agent_req = bind_agent_req;
303
304    let uri_str = format!("{}/v1/visor/machines/{id}/agent", configuration.base_path, id=crate::apis::urlencode(p_id));
305    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);
306
307    if let Some(ref user_agent) = configuration.user_agent {
308        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
309    }
310    if let Some(ref token) = configuration.bearer_access_token {
311        req_builder = req_builder.bearer_auth(token.to_owned());
312    };
313    req_builder = req_builder.json(&p_bind_agent_req);
314
315    let req = req_builder.build()?;
316    let resp = configuration.client.execute(req).await?;
317
318    let status = resp.status();
319    let content_type = resp
320        .headers()
321        .get("content-type")
322        .and_then(|v| v.to_str().ok())
323        .unwrap_or("application/octet-stream");
324    let content_type = super::ContentType::from(content_type);
325
326    if !status.is_client_error() && !status.is_server_error() {
327        let content = resp.text().await?;
328        match content_type {
329            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
330            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AgentBinding`"))),
331            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AgentBinding`")))),
332        }
333    } else {
334        let content = resp.text().await?;
335        let entity: Option<BindMachineAgentError> = serde_json::from_str(&content).ok();
336        Err(Error::ResponseError(ResponseContent { status, content, entity }))
337    }
338}
339
340/// Cancels a queued or running render in the caller's org. The engine cancel is org-scoped, so a tenant can only ever cancel its OWN job: a job in another tenant's shard is 404, exactly like one that never existed. An already-finished job is 409.
341pub async fn cancel_fleet_job(configuration: &configuration::Configuration, id: &str, job_cancel: models::JobCancel) -> Result<models::JobCanceled, Error<CancelFleetJobError>> {
342    // add a prefix to parameters to efficiently prevent name collisions
343    let p_id = id;
344    let p_job_cancel = job_cancel;
345
346    let uri_str = format!("{}/v1/visor/fleet/jobs/{id}/cancel", configuration.base_path, id=crate::apis::urlencode(p_id));
347    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
348
349    if let Some(ref user_agent) = configuration.user_agent {
350        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
351    }
352    if let Some(ref token) = configuration.bearer_access_token {
353        req_builder = req_builder.bearer_auth(token.to_owned());
354    };
355    req_builder = req_builder.json(&p_job_cancel);
356
357    let req = req_builder.build()?;
358    let resp = configuration.client.execute(req).await?;
359
360    let status = resp.status();
361    let content_type = resp
362        .headers()
363        .get("content-type")
364        .and_then(|v| v.to_str().ok())
365        .unwrap_or("application/octet-stream");
366    let content_type = super::ContentType::from(content_type);
367
368    if !status.is_client_error() && !status.is_server_error() {
369        let content = resp.text().await?;
370        match content_type {
371            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
372            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::JobCanceled`"))),
373            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::JobCanceled`")))),
374        }
375    } else {
376        let content = resp.text().await?;
377        let entity: Option<CancelFleetJobError> = serde_json::from_str(&content).ok();
378        Err(Error::ResponseError(ResponseContent { status, content, entity }))
379    }
380}
381
382/// Provisions a DOKS cluster for the caller's org and answers 201. ADMIN-GATED — a SuperAdmin, or an OrgAdmin of the caller's own org — because provisioning spends real infrastructure on the house account. The request is validated at this boundary, then Visor owns provisioning and the hanzo-org ownership tag.
383pub async fn create_kubernetes_cluster(configuration: &configuration::Configuration, create_cluster_req: models::CreateClusterReq) -> Result<models::ClusterView, Error<CreateKubernetesClusterError>> {
384    // add a prefix to parameters to efficiently prevent name collisions
385    let p_create_cluster_req = create_cluster_req;
386
387    let uri_str = format!("{}/v1/visor/k8s/clusters", configuration.base_path);
388    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
389
390    if let Some(ref user_agent) = configuration.user_agent {
391        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
392    }
393    if let Some(ref token) = configuration.bearer_access_token {
394        req_builder = req_builder.bearer_auth(token.to_owned());
395    };
396    req_builder = req_builder.json(&p_create_cluster_req);
397
398    let req = req_builder.build()?;
399    let resp = configuration.client.execute(req).await?;
400
401    let status = resp.status();
402    let content_type = resp
403        .headers()
404        .get("content-type")
405        .and_then(|v| v.to_str().ok())
406        .unwrap_or("application/octet-stream");
407    let content_type = super::ContentType::from(content_type);
408
409    if !status.is_client_error() && !status.is_server_error() {
410        let content = resp.text().await?;
411        match content_type {
412            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
413            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterView`"))),
414            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterView`")))),
415        }
416    } else {
417        let content = resp.text().await?;
418        let entity: Option<CreateKubernetesClusterError> = serde_json::from_str(&content).ok();
419        Err(Error::ResponseError(ResponseContent { status, content, entity }))
420    }
421}
422
423/// Adds a node pool to one of the caller org's clusters and answers 201 with the created pool. Only the CreateNodePoolSpec fields are forwarded; owner/provider/clusterId ride in the query exactly as Visor expects them.
424pub async fn create_node_pool(configuration: &configuration::Configuration, cluster_id: &str, pool_create: models::PoolCreate) -> Result<models::NodePoolView, Error<CreateNodePoolError>> {
425    // add a prefix to parameters to efficiently prevent name collisions
426    let p_cluster_id = cluster_id;
427    let p_pool_create = pool_create;
428
429    let uri_str = format!("{}/v1/visor/clusters/{clusterId}/pools", configuration.base_path, clusterId=crate::apis::urlencode(p_cluster_id));
430    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
431
432    if let Some(ref user_agent) = configuration.user_agent {
433        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
434    }
435    if let Some(ref token) = configuration.bearer_access_token {
436        req_builder = req_builder.bearer_auth(token.to_owned());
437    };
438    req_builder = req_builder.json(&p_pool_create);
439
440    let req = req_builder.build()?;
441    let resp = configuration.client.execute(req).await?;
442
443    let status = resp.status();
444    let content_type = resp
445        .headers()
446        .get("content-type")
447        .and_then(|v| v.to_str().ok())
448        .unwrap_or("application/octet-stream");
449    let content_type = super::ContentType::from(content_type);
450
451    if !status.is_client_error() && !status.is_server_error() {
452        let content = resp.text().await?;
453        match content_type {
454            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
455            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::NodePoolView`"))),
456            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::NodePoolView`")))),
457        }
458    } else {
459        let content = resp.text().await?;
460        let entity: Option<CreateNodePoolError> = serde_json::from_str(&content).ok();
461        Err(Error::ResponseError(ResponseContent { status, content, entity }))
462    }
463}
464
465/// Tears down both halves of a bot: it unbinds the agent (best-effort — a bot with no binding still deletes), then terminates the machine. Answers 204.
466pub async fn delete_bot(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<DeleteBotError>> {
467    // add a prefix to parameters to efficiently prevent name collisions
468    let p_id = id;
469
470    let uri_str = format!("{}/v1/visor/compute/bots/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
471    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
472
473    if let Some(ref user_agent) = configuration.user_agent {
474        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
475    }
476    if let Some(ref token) = configuration.bearer_access_token {
477        req_builder = req_builder.bearer_auth(token.to_owned());
478    };
479
480    let req = req_builder.build()?;
481    let resp = configuration.client.execute(req).await?;
482
483    let status = resp.status();
484
485    if !status.is_client_error() && !status.is_server_error() {
486        Ok(())
487    } else {
488        let content = resp.text().await?;
489        let entity: Option<DeleteBotError> = serde_json::from_str(&content).ok();
490        Err(Error::ResponseError(ResponseContent { status, content, entity }))
491    }
492}
493
494/// Destroys a DOKS cluster by id and answers 204. ADMIN-GATED, like create. Visor scopes the delete to the org (refuses a foreign id), so this can only ever remove the caller org's own cluster.
495pub async fn delete_kubernetes_cluster(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<DeleteKubernetesClusterError>> {
496    // add a prefix to parameters to efficiently prevent name collisions
497    let p_id = id;
498
499    let uri_str = format!("{}/v1/visor/k8s/clusters/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
500    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
501
502    if let Some(ref user_agent) = configuration.user_agent {
503        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
504    }
505    if let Some(ref token) = configuration.bearer_access_token {
506        req_builder = req_builder.bearer_auth(token.to_owned());
507    };
508
509    let req = req_builder.build()?;
510    let resp = configuration.client.execute(req).await?;
511
512    let status = resp.status();
513
514    if !status.is_client_error() && !status.is_server_error() {
515        Ok(())
516    } else {
517        let content = resp.text().await?;
518        let entity: Option<DeleteKubernetesClusterError> = serde_json::from_str(&content).ok();
519        Err(Error::ResponseError(ResponseContent { status, content, entity }))
520    }
521}
522
523/// Terminates one of the caller org's machines. Visor takes the machine identity as owner+name, and the owner is the validated principal, so a caller can only ever terminate its own tenant's machine. Answers 204.
524pub async fn delete_machine(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<DeleteMachineError>> {
525    // add a prefix to parameters to efficiently prevent name collisions
526    let p_id = id;
527
528    let uri_str = format!("{}/v1/visor/machines/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
529    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
530
531    if let Some(ref user_agent) = configuration.user_agent {
532        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
533    }
534    if let Some(ref token) = configuration.bearer_access_token {
535        req_builder = req_builder.bearer_auth(token.to_owned());
536    };
537
538    let req = req_builder.build()?;
539    let resp = configuration.client.execute(req).await?;
540
541    let status = resp.status();
542
543    if !status.is_client_error() && !status.is_server_error() {
544        Ok(())
545    } else {
546        let content = resp.text().await?;
547        let entity: Option<DeleteMachineError> = serde_json::from_str(&content).ok();
548        Err(Error::ResponseError(ResponseContent { status, content, entity }))
549    }
550}
551
552/// Removes a node pool from one of the caller org's clusters. The owner scopes the delete to the caller's tenant; provider+clusterId drive the provider-side removal. Answers 204.
553pub async fn delete_node_pool(configuration: &configuration::Configuration, cluster_id: &str, pool_id: &str, provider: Option<&str>) -> Result<(), Error<DeleteNodePoolError>> {
554    // add a prefix to parameters to efficiently prevent name collisions
555    let p_cluster_id = cluster_id;
556    let p_pool_id = pool_id;
557    let p_provider = provider;
558
559    let uri_str = format!("{}/v1/visor/clusters/{clusterId}/pools/{poolId}", configuration.base_path, clusterId=crate::apis::urlencode(p_cluster_id), poolId=crate::apis::urlencode(p_pool_id));
560    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
561
562    if let Some(ref param_value) = p_provider {
563        req_builder = req_builder.query(&[("provider", &param_value.to_string())]);
564    }
565    if let Some(ref user_agent) = configuration.user_agent {
566        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
567    }
568    if let Some(ref token) = configuration.bearer_access_token {
569        req_builder = req_builder.bearer_auth(token.to_owned());
570    };
571
572    let req = req_builder.build()?;
573    let resp = configuration.client.execute(req).await?;
574
575    let status = resp.status();
576
577    if !status.is_client_error() && !status.is_server_error() {
578        Ok(())
579    } else {
580        let content = resp.text().await?;
581        let entity: Option<DeleteNodePoolError> = serde_json::from_str(&content).ok();
582        Err(Error::ResponseError(ResponseContent { status, content, entity }))
583    }
584}
585
586/// Removes a BYO cluster from the caller org's fleet. It only ever touches BYO clusters — a managed cluster's nodes are removed through the node-pool routes — and answers 404 when the name is not in this org's fleet.
587pub async fn detach_cluster(configuration: &configuration::Configuration, id: &str) -> Result<models::ClusterDetached, Error<DetachClusterError>> {
588    // add a prefix to parameters to efficiently prevent name collisions
589    let p_id = id;
590
591    let uri_str = format!("{}/v1/visor/clusters/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
592    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
593
594    if let Some(ref user_agent) = configuration.user_agent {
595        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
596    }
597    if let Some(ref token) = configuration.bearer_access_token {
598        req_builder = req_builder.bearer_auth(token.to_owned());
599    };
600
601    let req = req_builder.build()?;
602    let resp = configuration.client.execute(req).await?;
603
604    let status = resp.status();
605    let content_type = resp
606        .headers()
607        .get("content-type")
608        .and_then(|v| v.to_str().ok())
609        .unwrap_or("application/octet-stream");
610    let content_type = super::ContentType::from(content_type);
611
612    if !status.is_client_error() && !status.is_server_error() {
613        let content = resp.text().await?;
614        match content_type {
615            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
616            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterDetached`"))),
617            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterDetached`")))),
618        }
619    } else {
620        let content = resp.text().await?;
621        let entity: Option<DetachClusterError> = serde_json::from_str(&content).ok();
622        Err(Error::ResponseError(ResponseContent { status, content, entity }))
623    }
624}
625
626/// Returns one of the caller org's bot machines with its agent binding.  A machine counts as a Bot if it carries the hanzo-kind:bot tag OR has an agent binding — either signal is authoritative, so a bot resolves even before its cloud-init has stamped every tag. A machine that is neither is 404: this route answers for bots, not for machines.
627pub async fn get_bot(configuration: &configuration::Configuration, id: &str) -> Result<models::BotView, Error<GetBotError>> {
628    // add a prefix to parameters to efficiently prevent name collisions
629    let p_id = id;
630
631    let uri_str = format!("{}/v1/visor/compute/bots/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
632    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
633
634    if let Some(ref user_agent) = configuration.user_agent {
635        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
636    }
637    if let Some(ref token) = configuration.bearer_access_token {
638        req_builder = req_builder.bearer_auth(token.to_owned());
639    };
640
641    let req = req_builder.build()?;
642    let resp = configuration.client.execute(req).await?;
643
644    let status = resp.status();
645    let content_type = resp
646        .headers()
647        .get("content-type")
648        .and_then(|v| v.to_str().ok())
649        .unwrap_or("application/octet-stream");
650    let content_type = super::ContentType::from(content_type);
651
652    if !status.is_client_error() && !status.is_server_error() {
653        let content = resp.text().await?;
654        match content_type {
655            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
656            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BotView`"))),
657            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BotView`")))),
658        }
659    } else {
660        let content = resp.text().await?;
661        let entity: Option<GetBotError> = serde_json::from_str(&content).ok();
662        Err(Error::ResponseError(ResponseContent { status, content, entity }))
663    }
664}
665
666/// Returns one cluster's detail: node pools + worker nodes. Visor scopes the lookup to the org (a foreign or missing id resolves to not-found), so a tenant can never read another tenant's cluster by guessing an id.
667pub async fn get_kubernetes_cluster(configuration: &configuration::Configuration, id: &str) -> Result<models::ClusterDetailView, Error<GetKubernetesClusterError>> {
668    // add a prefix to parameters to efficiently prevent name collisions
669    let p_id = id;
670
671    let uri_str = format!("{}/v1/visor/k8s/clusters/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
672    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
673
674    if let Some(ref user_agent) = configuration.user_agent {
675        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
676    }
677    if let Some(ref token) = configuration.bearer_access_token {
678        req_builder = req_builder.bearer_auth(token.to_owned());
679    };
680
681    let req = req_builder.build()?;
682    let resp = configuration.client.execute(req).await?;
683
684    let status = resp.status();
685    let content_type = resp
686        .headers()
687        .get("content-type")
688        .and_then(|v| v.to_str().ok())
689        .unwrap_or("application/octet-stream");
690    let content_type = super::ContentType::from(content_type);
691
692    if !status.is_client_error() && !status.is_server_error() {
693        let content = resp.text().await?;
694        match content_type {
695            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
696            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterDetailView`"))),
697            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterDetailView`")))),
698        }
699    } else {
700        let content = resp.text().await?;
701        let entity: Option<GetKubernetesClusterError> = serde_json::from_str(&content).ok();
702        Err(Error::ResponseError(ResponseContent { status, content, entity }))
703    }
704}
705
706/// Returns one of the caller org's machines by its org-scoped name. Visor keys the lookup by owner/name, so an id belonging to another tenant resolves to not-found rather than another org's machine.
707pub async fn get_machine(configuration: &configuration::Configuration, id: &str) -> Result<models::MachineView, Error<GetMachineError>> {
708    // add a prefix to parameters to efficiently prevent name collisions
709    let p_id = id;
710
711    let uri_str = format!("{}/v1/visor/machines/{id}", configuration.base_path, id=crate::apis::urlencode(p_id));
712    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
713
714    if let Some(ref user_agent) = configuration.user_agent {
715        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
716    }
717    if let Some(ref token) = configuration.bearer_access_token {
718        req_builder = req_builder.bearer_auth(token.to_owned());
719    };
720
721    let req = req_builder.build()?;
722    let resp = configuration.client.execute(req).await?;
723
724    let status = resp.status();
725    let content_type = resp
726        .headers()
727        .get("content-type")
728        .and_then(|v| v.to_str().ok())
729        .unwrap_or("application/octet-stream");
730    let content_type = super::ContentType::from(content_type);
731
732    if !status.is_client_error() && !status.is_server_error() {
733        let content = resp.text().await?;
734        match content_type {
735            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
736            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::MachineView`"))),
737            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::MachineView`")))),
738        }
739    } else {
740        let content = resp.text().await?;
741        let entity: Option<GetMachineError> = serde_json::from_str(&content).ok();
742        Err(Error::ResponseError(ResponseContent { status, content, entity }))
743    }
744}
745
746/// Returns the agent binding of one of the caller org's machines, or 404 when the machine runs no bot runtime.
747pub async fn get_machine_agent(configuration: &configuration::Configuration, id: &str) -> Result<models::AgentBinding, Error<GetMachineAgentError>> {
748    // add a prefix to parameters to efficiently prevent name collisions
749    let p_id = id;
750
751    let uri_str = format!("{}/v1/visor/machines/{id}/agent", configuration.base_path, id=crate::apis::urlencode(p_id));
752    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
753
754    if let Some(ref user_agent) = configuration.user_agent {
755        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
756    }
757    if let Some(ref token) = configuration.bearer_access_token {
758        req_builder = req_builder.bearer_auth(token.to_owned());
759    };
760
761    let req = req_builder.build()?;
762    let resp = configuration.client.execute(req).await?;
763
764    let status = resp.status();
765    let content_type = resp
766        .headers()
767        .get("content-type")
768        .and_then(|v| v.to_str().ok())
769        .unwrap_or("application/octet-stream");
770    let content_type = super::ContentType::from(content_type);
771
772    if !status.is_client_error() && !status.is_server_error() {
773        let content = resp.text().await?;
774        match content_type {
775            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
776            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AgentBinding`"))),
777            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AgentBinding`")))),
778        }
779    } else {
780        let content = resp.text().await?;
781        let entity: Option<GetMachineAgentError> = serde_json::from_str(&content).ok();
782        Err(Error::ResponseError(ResponseContent { status, content, entity }))
783    }
784}
785
786/// Regions lists the regions a machine can be launched in.  The catalog is GLOBAL — identical for every tenant — so no owner is forwarded upstream. It is still org-gated, because a catalog is a map of what this deployment can spend money in and an anonymous caller has no business reading it.
787pub async fn get_visor_compute_regions(configuration: &configuration::Configuration, ) -> Result<serde_json::Value, Error<GetVisorComputeRegionsError>> {
788
789    let uri_str = format!("{}/v1/visor/compute/regions", configuration.base_path);
790    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
791
792    if let Some(ref user_agent) = configuration.user_agent {
793        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
794    }
795    if let Some(ref token) = configuration.bearer_access_token {
796        req_builder = req_builder.bearer_auth(token.to_owned());
797    };
798
799    let req = req_builder.build()?;
800    let resp = configuration.client.execute(req).await?;
801
802    let status = resp.status();
803    let content_type = resp
804        .headers()
805        .get("content-type")
806        .and_then(|v| v.to_str().ok())
807        .unwrap_or("application/octet-stream");
808    let content_type = super::ContentType::from(content_type);
809
810    if !status.is_client_error() && !status.is_server_error() {
811        let content = resp.text().await?;
812        match content_type {
813            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
814            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
815            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
816        }
817    } else {
818        let content = resp.text().await?;
819        let entity: Option<GetVisorComputeRegionsError> = serde_json::from_str(&content).ok();
820        Err(Error::ResponseError(ResponseContent { status, content, entity }))
821    }
822}
823
824/// Sizes lists the machine sizes available to launch, with their specifications.  Global and org-gated, exactly as the region catalog is, and for the same reasons.
825pub async fn get_visor_compute_sizes(configuration: &configuration::Configuration, ) -> Result<serde_json::Value, Error<GetVisorComputeSizesError>> {
826
827    let uri_str = format!("{}/v1/visor/compute/sizes", configuration.base_path);
828    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
829
830    if let Some(ref user_agent) = configuration.user_agent {
831        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
832    }
833    if let Some(ref token) = configuration.bearer_access_token {
834        req_builder = req_builder.bearer_auth(token.to_owned());
835    };
836
837    let req = req_builder.build()?;
838    let resp = configuration.client.execute(req).await?;
839
840    let status = resp.status();
841    let content_type = resp
842        .headers()
843        .get("content-type")
844        .and_then(|v| v.to_str().ok())
845        .unwrap_or("application/octet-stream");
846    let content_type = super::ContentType::from(content_type);
847
848    if !status.is_client_error() && !status.is_server_error() {
849        let content = resp.text().await?;
850        match content_type {
851            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
852            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
853            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
854        }
855    } else {
856        let content = resp.text().await?;
857        let entity: Option<GetVisorComputeSizesError> = serde_json::from_str(&content).ok();
858        Err(Error::ResponseError(ResponseContent { status, content, entity }))
859    }
860}
861
862/// Returns the caller org's bot machines — the kind=bot machines — each joined with the agent binding that says which cloud Agent it runs.  The bindings are read ONCE and joined by machine id, so the list is O(1) upstream calls, not N+1. A bindings read that fails only costs the reconciled status: a bot still lists without it.
863pub async fn list_bots(configuration: &configuration::Configuration, ) -> Result<models::BotList, Error<ListBotsError>> {
864
865    let uri_str = format!("{}/v1/visor/compute/bots", configuration.base_path);
866    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
867
868    if let Some(ref user_agent) = configuration.user_agent {
869        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
870    }
871    if let Some(ref token) = configuration.bearer_access_token {
872        req_builder = req_builder.bearer_auth(token.to_owned());
873    };
874
875    let req = req_builder.build()?;
876    let resp = configuration.client.execute(req).await?;
877
878    let status = resp.status();
879    let content_type = resp
880        .headers()
881        .get("content-type")
882        .and_then(|v| v.to_str().ok())
883        .unwrap_or("application/octet-stream");
884    let content_type = super::ContentType::from(content_type);
885
886    if !status.is_client_error() && !status.is_server_error() {
887        let content = resp.text().await?;
888        match content_type {
889            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
890            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BotList`"))),
891            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BotList`")))),
892        }
893    } else {
894        let content = resp.text().await?;
895        let entity: Option<ListBotsError> = serde_json::from_str(&content).ok();
896        Err(Error::ResponseError(ResponseContent { status, content, entity }))
897    }
898}
899
900/// Returns the caller org's clusters from both sources: the managed clusters projected from Visor's node pools, and the BYO clusters attached to the caller's project. A Visor outage costs the managed half only — the BYO half still lists, because a page that 502s on an optional provider is worse than a page that shows what it can.
901pub async fn list_clusters(configuration: &configuration::Configuration, ) -> Result<models::ClusterList, Error<ListClustersError>> {
902
903    let uri_str = format!("{}/v1/visor/clusters", configuration.base_path);
904    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
905
906    if let Some(ref user_agent) = configuration.user_agent {
907        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
908    }
909    if let Some(ref token) = configuration.bearer_access_token {
910        req_builder = req_builder.bearer_auth(token.to_owned());
911    };
912
913    let req = req_builder.build()?;
914    let resp = configuration.client.execute(req).await?;
915
916    let status = resp.status();
917    let content_type = resp
918        .headers()
919        .get("content-type")
920        .and_then(|v| v.to_str().ok())
921        .unwrap_or("application/octet-stream");
922    let content_type = super::ContentType::from(content_type);
923
924    if !status.is_client_error() && !status.is_server_error() {
925        let content = resp.text().await?;
926        match content_type {
927            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
928            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterList`"))),
929            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterList`")))),
930        }
931    } else {
932        let content = resp.text().await?;
933        let entity: Option<ListClustersError> = serde_json::from_str(&content).ok();
934        Err(Error::ResponseError(ResponseContent { status, content, entity }))
935    }
936}
937
938/// Returns every compute unit the caller's org has, from every source, each carrying its latest utilization: agent run-targets, the BYO machines that dialed in, attached BYO clusters and Visor-provisioned machines.  A unit with a live snapshot of its own keeps it; the rest are overlaid from the utilization series, and only when the sample agrees about the SOURCE — two planes could mint the same unit id, and a board must never show one machine's load on another's row. BYO GPU units also carry their gpu-jobs queue depth. Every source is folded in independently: a broken one costs its own rows and nothing else.
939pub async fn list_fleet(configuration: &configuration::Configuration, ) -> Result<models::FleetBoard, Error<ListFleetError>> {
940
941    let uri_str = format!("{}/v1/visor/fleet", configuration.base_path);
942    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
943
944    if let Some(ref user_agent) = configuration.user_agent {
945        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
946    }
947    if let Some(ref token) = configuration.bearer_access_token {
948        req_builder = req_builder.bearer_auth(token.to_owned());
949    };
950
951    let req = req_builder.build()?;
952    let resp = configuration.client.execute(req).await?;
953
954    let status = resp.status();
955    let content_type = resp
956        .headers()
957        .get("content-type")
958        .and_then(|v| v.to_str().ok())
959        .unwrap_or("application/octet-stream");
960    let content_type = super::ContentType::from(content_type);
961
962    if !status.is_client_error() && !status.is_server_error() {
963        let content = resp.text().await?;
964        match content_type {
965            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
966            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FleetBoard`"))),
967            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FleetBoard`")))),
968        }
969    } else {
970        let content = resp.text().await?;
971        let entity: Option<ListFleetError> = serde_json::from_str(&content).ok();
972        Err(Error::ResponseError(ResponseContent { status, content, entity }))
973    }
974}
975
976/// Returns the caller org's gpu-jobs render queue, each row tagged with the GPU it targets (empty = the shared any-GPU lane) and the node claiming it, optionally narrowed to one GPU's queue and/or one status.  A job whose worker died — STARTED with an elapsed lease and not yet reclaimed — reads \"stalled\", not \"running\". Fail-soft: an unavailable tasks engine yields an empty queue rather than an error.
977pub async fn list_fleet_jobs(configuration: &configuration::Configuration, gpu: Option<&str>, status: Option<&str>) -> Result<models::JobList, Error<ListFleetJobsError>> {
978    // add a prefix to parameters to efficiently prevent name collisions
979    let p_gpu = gpu;
980    let p_status = status;
981
982    let uri_str = format!("{}/v1/visor/fleet/jobs", configuration.base_path);
983    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
984
985    if let Some(ref param_value) = p_gpu {
986        req_builder = req_builder.query(&[("gpu", &param_value.to_string())]);
987    }
988    if let Some(ref param_value) = p_status {
989        req_builder = req_builder.query(&[("status", &param_value.to_string())]);
990    }
991    if let Some(ref user_agent) = configuration.user_agent {
992        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
993    }
994    if let Some(ref token) = configuration.bearer_access_token {
995        req_builder = req_builder.bearer_auth(token.to_owned());
996    };
997
998    let req = req_builder.build()?;
999    let resp = configuration.client.execute(req).await?;
1000
1001    let status = resp.status();
1002    let content_type = resp
1003        .headers()
1004        .get("content-type")
1005        .and_then(|v| v.to_str().ok())
1006        .unwrap_or("application/octet-stream");
1007    let content_type = super::ContentType::from(content_type);
1008
1009    if !status.is_client_error() && !status.is_server_error() {
1010        let content = resp.text().await?;
1011        match content_type {
1012            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1013            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::JobList`"))),
1014            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::JobList`")))),
1015        }
1016    } else {
1017        let content = resp.text().await?;
1018        let entity: Option<ListFleetJobsError> = serde_json::from_str(&content).ok();
1019        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1020    }
1021}
1022
1023/// Returns the caller org's utilization series, oldest first.  A rejected narrower is a 400 carrying its own reason (the vocabulary is ours and safe to echo); a warehouse failure is logged and answered 503 \"unavailable\", because a chart that silently reads \"no load\" when the truth is \"we cannot tell\" is worse than one that says so. An ABSENT warehouse is different again: it returns an empty series, which renders honestly as \"no samples yet\".
1024pub async fn list_fleet_samples(configuration: &configuration::Configuration, unit: Option<&str>, source: Option<&str>, range: Option<&str>) -> Result<models::SampleList, Error<ListFleetSamplesError>> {
1025    // add a prefix to parameters to efficiently prevent name collisions
1026    let p_unit = unit;
1027    let p_source = source;
1028    let p_range = range;
1029
1030    let uri_str = format!("{}/v1/visor/fleet/samples", configuration.base_path);
1031    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1032
1033    if let Some(ref param_value) = p_unit {
1034        req_builder = req_builder.query(&[("unit", &param_value.to_string())]);
1035    }
1036    if let Some(ref param_value) = p_source {
1037        req_builder = req_builder.query(&[("source", &param_value.to_string())]);
1038    }
1039    if let Some(ref param_value) = p_range {
1040        req_builder = req_builder.query(&[("range", &param_value.to_string())]);
1041    }
1042    if let Some(ref user_agent) = configuration.user_agent {
1043        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1044    }
1045    if let Some(ref token) = configuration.bearer_access_token {
1046        req_builder = req_builder.bearer_auth(token.to_owned());
1047    };
1048
1049    let req = req_builder.build()?;
1050    let resp = configuration.client.execute(req).await?;
1051
1052    let status = resp.status();
1053    let content_type = resp
1054        .headers()
1055        .get("content-type")
1056        .and_then(|v| v.to_str().ok())
1057        .unwrap_or("application/octet-stream");
1058    let content_type = super::ContentType::from(content_type);
1059
1060    if !status.is_client_error() && !status.is_server_error() {
1061        let content = resp.text().await?;
1062        match content_type {
1063            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1064            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SampleList`"))),
1065            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SampleList`")))),
1066        }
1067    } else {
1068        let content = resp.text().await?;
1069        let entity: Option<ListFleetSamplesError> = serde_json::from_str(&content).ok();
1070        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1071    }
1072}
1073
1074/// Returns the caller org's BYO machines — the ones that dialed in via `hanzo link` — with everything each host reported about itself. The Machines and GPUs pages fold the same data into their normalized shapes; this is the canonical raw list a fleet view (or the CLI's `status`) reads.
1075pub async fn list_fleet_workers(configuration: &configuration::Configuration, ) -> Result<models::WorkerList, Error<ListFleetWorkersError>> {
1076
1077    let uri_str = format!("{}/v1/visor/fleet/workers", configuration.base_path);
1078    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1079
1080    if let Some(ref user_agent) = configuration.user_agent {
1081        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1082    }
1083    if let Some(ref token) = configuration.bearer_access_token {
1084        req_builder = req_builder.bearer_auth(token.to_owned());
1085    };
1086
1087    let req = req_builder.build()?;
1088    let resp = configuration.client.execute(req).await?;
1089
1090    let status = resp.status();
1091    let content_type = resp
1092        .headers()
1093        .get("content-type")
1094        .and_then(|v| v.to_str().ok())
1095        .unwrap_or("application/octet-stream");
1096    let content_type = super::ContentType::from(content_type);
1097
1098    if !status.is_client_error() && !status.is_server_error() {
1099        let content = resp.text().await?;
1100        match content_type {
1101            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1102            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::WorkerList`"))),
1103            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::WorkerList`")))),
1104        }
1105    } else {
1106        let content = resp.text().await?;
1107        let entity: Option<ListFleetWorkersError> = serde_json::from_str(&content).ok();
1108        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1109    }
1110}
1111
1112/// Is an HONEST empty surface: Visor exposes no GPU alert inventory, so this returns [] rather than fabricating alerts. It stays a real, tenant-gated route so the console's alerts fetch resolves (200 [], not a 404) — an honest \"no alerts\", the same discipline the rest of the surface follows.
1113pub async fn list_gpu_alerts(configuration: &configuration::Configuration, ) -> Result<models::GpuAlertList, Error<ListGpuAlertsError>> {
1114
1115    let uri_str = format!("{}/v1/visor/gpus/alerts", configuration.base_path);
1116    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1117
1118    if let Some(ref user_agent) = configuration.user_agent {
1119        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1120    }
1121    if let Some(ref token) = configuration.bearer_access_token {
1122        req_builder = req_builder.bearer_auth(token.to_owned());
1123    };
1124
1125    let req = req_builder.build()?;
1126    let resp = configuration.client.execute(req).await?;
1127
1128    let status = resp.status();
1129    let content_type = resp
1130        .headers()
1131        .get("content-type")
1132        .and_then(|v| v.to_str().ok())
1133        .unwrap_or("application/octet-stream");
1134    let content_type = super::ContentType::from(content_type);
1135
1136    if !status.is_client_error() && !status.is_server_error() {
1137        let content = resp.text().await?;
1138        match content_type {
1139            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1140            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GpuAlertList`"))),
1141            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GpuAlertList`")))),
1142        }
1143    } else {
1144        let content = resp.text().await?;
1145        let entity: Option<ListGpuAlertsError> = serde_json::from_str(&content).ok();
1146        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1147    }
1148}
1149
1150/// Returns one row per physical accelerator the caller's org has, derived from its real GPU machines (the size slug says how many cards a node holds) and from the accelerators BYO workers report through nvidia-smi.  Live telemetry is absent on Visor rows because Visor's machine object carries none — an honest omission the console renders as \"—\", never a fabricated 0.
1151pub async fn list_gpus(configuration: &configuration::Configuration, ) -> Result<models::GpuList, Error<ListGpusError>> {
1152
1153    let uri_str = format!("{}/v1/visor/gpus", configuration.base_path);
1154    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1155
1156    if let Some(ref user_agent) = configuration.user_agent {
1157        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1158    }
1159    if let Some(ref token) = configuration.bearer_access_token {
1160        req_builder = req_builder.bearer_auth(token.to_owned());
1161    };
1162
1163    let req = req_builder.build()?;
1164    let resp = configuration.client.execute(req).await?;
1165
1166    let status = resp.status();
1167    let content_type = resp
1168        .headers()
1169        .get("content-type")
1170        .and_then(|v| v.to_str().ok())
1171        .unwrap_or("application/octet-stream");
1172    let content_type = super::ContentType::from(content_type);
1173
1174    if !status.is_client_error() && !status.is_server_error() {
1175        let content = resp.text().await?;
1176        match content_type {
1177            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1178            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GpuList`"))),
1179            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GpuList`")))),
1180        }
1181    } else {
1182        let content = resp.text().await?;
1183        let entity: Option<ListGpusError> = serde_json::from_str(&content).ok();
1184        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1185    }
1186}
1187
1188/// Lists the org's DOKS clusters (Visor, house account) folded with the org's BYO clusters — ONE fleet cluster view under the unified k8s noun. A Visor outage is logged and skipped so a down optional provider never hides the BYO list.
1189pub async fn list_kubernetes_clusters(configuration: &configuration::Configuration, ) -> Result<models::ClusterList, Error<ListKubernetesClustersError>> {
1190
1191    let uri_str = format!("{}/v1/visor/k8s/clusters", configuration.base_path);
1192    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1193
1194    if let Some(ref user_agent) = configuration.user_agent {
1195        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1196    }
1197    if let Some(ref token) = configuration.bearer_access_token {
1198        req_builder = req_builder.bearer_auth(token.to_owned());
1199    };
1200
1201    let req = req_builder.build()?;
1202    let resp = configuration.client.execute(req).await?;
1203
1204    let status = resp.status();
1205    let content_type = resp
1206        .headers()
1207        .get("content-type")
1208        .and_then(|v| v.to_str().ok())
1209        .unwrap_or("application/octet-stream");
1210    let content_type = super::ContentType::from(content_type);
1211
1212    if !status.is_client_error() && !status.is_server_error() {
1213        let content = resp.text().await?;
1214        match content_type {
1215            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1216            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ClusterList`"))),
1217            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ClusterList`")))),
1218        }
1219    } else {
1220        let content = resp.text().await?;
1221        let entity: Option<ListKubernetesClustersError> = serde_json::from_str(&content).ok();
1222        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1223    }
1224}
1225
1226/// Returns every DOKS worker node in the org's clusters as a machine — the SAME set the fleet folds in (managedMachines), exposed directly under the k8s noun. House account (hanzo-org cluster tag) + BYOC, deduped by Visor.
1227pub async fn list_kubernetes_nodes(configuration: &configuration::Configuration, ) -> Result<models::NodeList, Error<ListKubernetesNodesError>> {
1228
1229    let uri_str = format!("{}/v1/visor/k8s/nodes", configuration.base_path);
1230    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1231
1232    if let Some(ref user_agent) = configuration.user_agent {
1233        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1234    }
1235    if let Some(ref token) = configuration.bearer_access_token {
1236        req_builder = req_builder.bearer_auth(token.to_owned());
1237    };
1238
1239    let req = req_builder.build()?;
1240    let resp = configuration.client.execute(req).await?;
1241
1242    let status = resp.status();
1243    let content_type = resp
1244        .headers()
1245        .get("content-type")
1246        .and_then(|v| v.to_str().ok())
1247        .unwrap_or("application/octet-stream");
1248    let content_type = super::ContentType::from(content_type);
1249
1250    if !status.is_client_error() && !status.is_server_error() {
1251        let content = resp.text().await?;
1252        match content_type {
1253            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1254            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::NodeList`"))),
1255            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::NodeList`")))),
1256        }
1257    } else {
1258        let content = resp.text().await?;
1259        let entity: Option<ListKubernetesNodesError> = serde_json::from_str(&content).ok();
1260        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1261    }
1262}
1263
1264/// Returns every agent↔machine binding in the caller's org — which machines are running which cloud Agent, with vm's own reconciled status.
1265pub async fn list_machine_agents(configuration: &configuration::Configuration, ) -> Result<models::BindingList, Error<ListMachineAgentsError>> {
1266
1267    let uri_str = format!("{}/v1/visor/machines/agents", configuration.base_path);
1268    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1269
1270    if let Some(ref user_agent) = configuration.user_agent {
1271        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1272    }
1273    if let Some(ref token) = configuration.bearer_access_token {
1274        req_builder = req_builder.bearer_auth(token.to_owned());
1275    };
1276
1277    let req = req_builder.build()?;
1278    let resp = configuration.client.execute(req).await?;
1279
1280    let status = resp.status();
1281    let content_type = resp
1282        .headers()
1283        .get("content-type")
1284        .and_then(|v| v.to_str().ok())
1285        .unwrap_or("application/octet-stream");
1286    let content_type = super::ContentType::from(content_type);
1287
1288    if !status.is_client_error() && !status.is_server_error() {
1289        let content = resp.text().await?;
1290        match content_type {
1291            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1292            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BindingList`"))),
1293            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BindingList`")))),
1294        }
1295    } else {
1296        let content = resp.text().await?;
1297        let entity: Option<ListMachineAgentsError> = serde_json::from_str(&content).ok();
1298        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1299    }
1300}
1301
1302/// Returns every machine the caller's org has — Visor's registry, the live DigitalOcean droplets and the DOKS worker nodes (deduped into one union), plus the BYO machines that dialed in via `hanzo link` (provider \"byo\").  A source Visor cannot answer for is logged and skipped, never an error: one wedged upstream must not hide the machines the other sources can see.
1303pub async fn list_machines(configuration: &configuration::Configuration, ) -> Result<models::MachineList, Error<ListMachinesError>> {
1304
1305    let uri_str = format!("{}/v1/visor/machines", configuration.base_path);
1306    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
1307
1308    if let Some(ref user_agent) = configuration.user_agent {
1309        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1310    }
1311    if let Some(ref token) = configuration.bearer_access_token {
1312        req_builder = req_builder.bearer_auth(token.to_owned());
1313    };
1314
1315    let req = req_builder.build()?;
1316    let resp = configuration.client.execute(req).await?;
1317
1318    let status = resp.status();
1319    let content_type = resp
1320        .headers()
1321        .get("content-type")
1322        .and_then(|v| v.to_str().ok())
1323        .unwrap_or("application/octet-stream");
1324    let content_type = super::ContentType::from(content_type);
1325
1326    if !status.is_client_error() && !status.is_server_error() {
1327        let content = resp.text().await?;
1328        match content_type {
1329            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1330            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::MachineList`"))),
1331            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::MachineList`")))),
1332        }
1333    } else {
1334        let content = resp.text().await?;
1335        let entity: Option<ListMachinesError> = serde_json::from_str(&content).ok();
1336        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1337    }
1338}
1339
1340/// Dispatches one verb against a bot the caller's org owns. `message` runs the bot's bound agent with the request body as the message and streams the agent's answer back VERBATIM — the upstream body, its content type and its status — so a message is a real agent run, recorded, billed and traced exactly like any other, under the caller's own identity rather than a fabricated one. `stop` and `pause` are the same single honest capability: they halt the runtime by unbinding the agent while LEAVING THE MACHINE UP, so the bot stops answering but keeps costing — rebind to resume, or delete the bot to tear it down. Stopping is idempotent; a bot with no binding still reports stopped.  Org-scoped and fails closed: a validated principal is required (403 without one) and the bot is addressed under the caller's OWN org, so another tenant's id is not reachable. An unknown action is a clean 400 naming the three it accepts, never a silent no-op, and messaging a bot with no bound agent is a 400.
1341pub async fn post_visor_compute_bots_by_id_by_action(configuration: &configuration::Configuration, id: &str, action: &str) -> Result<(), Error<PostVisorComputeBotsByIdByActionError>> {
1342    // add a prefix to parameters to efficiently prevent name collisions
1343    let p_id = id;
1344    let p_action = action;
1345
1346    let uri_str = format!("{}/v1/visor/compute/bots/{id}/{action}", configuration.base_path, id=crate::apis::urlencode(p_id), action=crate::apis::urlencode(p_action));
1347    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
1348
1349    if let Some(ref user_agent) = configuration.user_agent {
1350        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1351    }
1352    if let Some(ref token) = configuration.bearer_access_token {
1353        req_builder = req_builder.bearer_auth(token.to_owned());
1354    };
1355
1356    let req = req_builder.build()?;
1357    let resp = configuration.client.execute(req).await?;
1358
1359    let status = resp.status();
1360
1361    if !status.is_client_error() && !status.is_server_error() {
1362        Ok(())
1363    } else {
1364        let content = resp.text().await?;
1365        let entity: Option<PostVisorComputeBotsByIdByActionError> = serde_json::from_str(&content).ok();
1366        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1367    }
1368}
1369
1370/// Creates BOTH halves of a bot in one call and answers 201 with the bot: the cloud agent it runs, then a bot-kind machine bootstrapped with the bot runtime, then the binding between them, so a launched bot is immediately messageable. Send `dryRun: true` for a price quote instead — 200 with the upstream quote verbatim, no agent created, no machine launched, nothing spent.  The agent is created FIRST and on purpose: it is create-if-absent (an agent that already exists is reused, so a relaunch is fine and several bots may share one explicit `agent`), and doing it before the machine means a bad request — a model that is not in the catalog, say — fails with the real reason BEFORE any metered machine is provisioned. `agent` defaults to the bot's name and an empty `model` takes the deployment default.  Org-scoped and fails closed: a validated principal is required (403 without one), the owning org is that principal's and never a body field, `size` is required (400), and `name` is required for a real launch though not for a quote.
1371pub async fn post_visor_compute_bots_launch(configuration: &configuration::Configuration, ) -> Result<(), Error<PostVisorComputeBotsLaunchError>> {
1372
1373    let uri_str = format!("{}/v1/visor/compute/bots/launch", configuration.base_path);
1374    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
1375
1376    if let Some(ref user_agent) = configuration.user_agent {
1377        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1378    }
1379    if let Some(ref token) = configuration.bearer_access_token {
1380        req_builder = req_builder.bearer_auth(token.to_owned());
1381    };
1382
1383    let req = req_builder.build()?;
1384    let resp = configuration.client.execute(req).await?;
1385
1386    let status = resp.status();
1387
1388    if !status.is_client_error() && !status.is_server_error() {
1389        Ok(())
1390    } else {
1391        let content = resp.text().await?;
1392        let entity: Option<PostVisorComputeBotsLaunchError> = serde_json::from_str(&content).ok();
1393        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1394    }
1395}
1396
1397/// Provisions a machine owned by the caller's org and answers 201 with the machine. Send `dryRun: true` to get a PRICE QUOTE instead: 200 with the upstream quote passed through verbatim, nothing launched and nothing spent. Two response shapes on one address is the rule to know, and it is why this is not a typed op.  Metering is not this plane's: the launch fronts the compute provider's resell endpoint, which owns the balance gate and the per-hour meter, and cloud only forwards the tenant. Ownership is the validated principal's org and is never read from the body, so a launch always lands in the caller's OWN tenant and the machine it creates is only ever visible to that tenant. Fails closed: a validated principal is required (403 without one) and `size` (or its `instanceType` alias) is required (400).
1398pub async fn post_visor_machines(configuration: &configuration::Configuration, ) -> Result<(), Error<PostVisorMachinesError>> {
1399
1400    let uri_str = format!("{}/v1/visor/machines", configuration.base_path);
1401    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
1402
1403    if let Some(ref user_agent) = configuration.user_agent {
1404        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1405    }
1406    if let Some(ref token) = configuration.bearer_access_token {
1407        req_builder = req_builder.bearer_auth(token.to_owned());
1408    };
1409
1410    let req = req_builder.build()?;
1411    let resp = configuration.client.execute(req).await?;
1412
1413    let status = resp.status();
1414
1415    if !status.is_client_error() && !status.is_server_error() {
1416        Ok(())
1417    } else {
1418        let content = resp.text().await?;
1419        let entity: Option<PostVisorMachinesError> = serde_json::from_str(&content).ok();
1420        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1421    }
1422}
1423
1424/// Records a BYO worker's live GPU utilization into the SAME series the fleet board overlays. The org is the validated principal and source/kind are fixed server-side, so a worker names only its own metrics — never another tenant or another source. Answers 202: the warehouse write is DETACHED (its own bounded context, never in the response path), so a slow or absent warehouse cannot stall a heartbeat.
1425pub async fn record_fleet_sample(configuration: &configuration::Configuration, sample_ingest: models::SampleIngest) -> Result<models::SampleAccepted, Error<RecordFleetSampleError>> {
1426    // add a prefix to parameters to efficiently prevent name collisions
1427    let p_sample_ingest = sample_ingest;
1428
1429    let uri_str = format!("{}/v1/visor/fleet/samples", configuration.base_path);
1430    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
1431
1432    if let Some(ref user_agent) = configuration.user_agent {
1433        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1434    }
1435    if let Some(ref token) = configuration.bearer_access_token {
1436        req_builder = req_builder.bearer_auth(token.to_owned());
1437    };
1438    req_builder = req_builder.json(&p_sample_ingest);
1439
1440    let req = req_builder.build()?;
1441    let resp = configuration.client.execute(req).await?;
1442
1443    let status = resp.status();
1444    let content_type = resp
1445        .headers()
1446        .get("content-type")
1447        .and_then(|v| v.to_str().ok())
1448        .unwrap_or("application/octet-stream");
1449    let content_type = super::ContentType::from(content_type);
1450
1451    if !status.is_client_error() && !status.is_server_error() {
1452        let content = resp.text().await?;
1453        match content_type {
1454            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1455            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SampleAccepted`"))),
1456            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SampleAccepted`")))),
1457        }
1458    } else {
1459        let content = resp.text().await?;
1460        let entity: Option<RecordFleetSampleError> = serde_json::from_str(&content).ok();
1461        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1462    }
1463}
1464
1465/// Resizes a node pool to an absolute node count and returns the pool as Visor reports it after the change.
1466pub async fn scale_node_pool(configuration: &configuration::Configuration, cluster_id: &str, pool_id: &str, pool_scale: models::PoolScale) -> Result<models::NodePoolView, Error<ScaleNodePoolError>> {
1467    // add a prefix to parameters to efficiently prevent name collisions
1468    let p_cluster_id = cluster_id;
1469    let p_pool_id = pool_id;
1470    let p_pool_scale = pool_scale;
1471
1472    let uri_str = format!("{}/v1/visor/clusters/{clusterId}/pools/{poolId}/scale", configuration.base_path, clusterId=crate::apis::urlencode(p_cluster_id), poolId=crate::apis::urlencode(p_pool_id));
1473    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
1474
1475    if let Some(ref user_agent) = configuration.user_agent {
1476        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1477    }
1478    if let Some(ref token) = configuration.bearer_access_token {
1479        req_builder = req_builder.bearer_auth(token.to_owned());
1480    };
1481    req_builder = req_builder.json(&p_pool_scale);
1482
1483    let req = req_builder.build()?;
1484    let resp = configuration.client.execute(req).await?;
1485
1486    let status = resp.status();
1487    let content_type = resp
1488        .headers()
1489        .get("content-type")
1490        .and_then(|v| v.to_str().ok())
1491        .unwrap_or("application/octet-stream");
1492    let content_type = super::ContentType::from(content_type);
1493
1494    if !status.is_client_error() && !status.is_server_error() {
1495        let content = resp.text().await?;
1496        match content_type {
1497            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
1498            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::NodePoolView`"))),
1499            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::NodePoolView`")))),
1500        }
1501    } else {
1502        let content = resp.text().await?;
1503        let entity: Option<ScaleNodePoolError> = serde_json::from_str(&content).ok();
1504        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1505    }
1506}
1507
1508/// Detaches the agent runtime from one of the caller org's machines. The machine stays — this halts the bot, it does not terminate the compute. Answers 204.
1509pub async fn unbind_machine_agent(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<UnbindMachineAgentError>> {
1510    // add a prefix to parameters to efficiently prevent name collisions
1511    let p_id = id;
1512
1513    let uri_str = format!("{}/v1/visor/machines/{id}/agent", configuration.base_path, id=crate::apis::urlencode(p_id));
1514    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
1515
1516    if let Some(ref user_agent) = configuration.user_agent {
1517        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1518    }
1519    if let Some(ref token) = configuration.bearer_access_token {
1520        req_builder = req_builder.bearer_auth(token.to_owned());
1521    };
1522
1523    let req = req_builder.build()?;
1524    let resp = configuration.client.execute(req).await?;
1525
1526    let status = resp.status();
1527
1528    if !status.is_client_error() && !status.is_server_error() {
1529        Ok(())
1530    } else {
1531        let content = resp.text().await?;
1532        let entity: Option<UnbindMachineAgentError> = serde_json::from_str(&content).ok();
1533        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1534    }
1535}
1536