bollard_next/
secret.rs

1//! Secret API: manage and inspect docker secrets within a swarm
2
3pub use crate::models::*;
4
5use super::Docker;
6use crate::{docker::BodyType, errors::Error};
7use bytes::Bytes;
8use http::request::Builder;
9use http_body_util::Full;
10use serde_derive::Serialize;
11use std::{collections::HashMap, hash::Hash};
12
13/// Parameters used in the [List Secret API](super::Docker::list_secrets())
14///
15/// ## Examples
16///
17/// ```rust
18/// # use std::collections::HashMap;
19/// # use std::default::Default;
20/// use bollard_next::secret::ListSecretsOptions;
21///
22/// let mut filters = HashMap::new();
23/// filters.insert("name", vec!["my-secret-name"]);
24///
25/// ListSecretsOptions{
26///     filters,
27/// };
28/// ```
29///
30/// ```rust
31/// # use bollard_next::secret::ListSecretsOptions;
32/// # use std::default::Default;
33///
34/// let options: ListSecretsOptions<&str> = Default::default();
35/// ```
36#[derive(Debug, Clone, Default, PartialEq, Serialize)]
37pub struct ListSecretsOptions<T>
38where
39    T: Into<String> + Eq + Hash + serde::ser::Serialize,
40{
41    /// Filters to process on the secret list, encoded as JSON. Available filters:
42    ///  - `id`=`<ID>` a secret's ID
43    ///  - `label`=`key` or `label`=`"key=value"` of a secret label
44    ///  - `name`=`<name>` a secret's name
45    ///  - `names`=`<name>` a multiple secret's name comma separated
46    #[serde(serialize_with = "crate::docker::serialize_as_json")]
47    pub filters: HashMap<T, Vec<T>>,
48}
49
50/// Parameters used in the [Update Secret API](Docker::update_secret())
51///
52/// ## Examples
53///
54/// ```rust
55/// use bollard_next::secret::UpdateSecretOptions;
56///
57/// UpdateSecretOptions{
58///     version: 1234,
59///     ..Default::default()
60/// };
61/// ```
62#[derive(Debug, Copy, Clone, Default, PartialEq, Serialize)]
63pub struct UpdateSecretOptions {
64    /// The version number of the secret object being updated. This is required to avoid conflicting writes. This version number should be the value as currently set on the secret before the update.
65    pub version: u64,
66}
67
68impl Docker {
69    /// ---
70    ///
71    /// # List Secrets
72    ///
73    /// Returns a list of secrets.
74    ///
75    /// # Arguments
76    ///
77    ///  - Optional [ListSecretsOptions](ListSecretsOptions) struct.
78    ///
79    /// # Returns
80    ///
81    ///  - Vector of [Secret](Secret), wrapped in a Future.
82    ///
83    /// # Examples
84    ///
85    /// ```rust
86    /// # use bollard_next::Docker;
87    /// # let docker = Docker::connect_with_http_defaults().unwrap();
88    /// use bollard_next::secret::ListSecretsOptions;
89    ///
90    /// use std::collections::HashMap;
91    /// use std::default::Default;
92    ///
93    /// let mut filters = HashMap::new();
94    /// filters.insert("label", vec!["secret-label=label-value"]);
95    ///
96    /// let options = Some(ListSecretsOptions{
97    ///     filters,
98    ///     ..Default::default()
99    /// });
100    ///
101    /// docker.list_secrets(options);
102    /// ```
103    pub async fn list_secrets<T>(
104        &self,
105        options: Option<ListSecretsOptions<T>>,
106    ) -> Result<Vec<Secret>, Error>
107    where
108        T: Into<String> + Eq + Hash + serde::ser::Serialize,
109    {
110        let url = "/secrets";
111
112        let req = self.build_request(
113            url,
114            Builder::new().method(hyper::Method::GET),
115            options,
116            Ok(BodyType::Left(Full::new(Bytes::new()))),
117        );
118
119        self.process_into_value(req).await
120    }
121
122    /// ---
123    ///
124    /// # Create Secret
125    ///
126    /// Create new secret on the docker swarm.
127    ///
128    /// # Arguments
129    ///
130    ///  - [SecretSpec](SecretSpec) struct.
131    ///
132    /// # Returns
133    ///
134    ///  - A [IdResponse](IdResponse) wrapped in a Future.
135    ///
136    /// # Examples
137    ///
138    /// ```rust
139    /// # use bollard_next::Docker;
140    /// # use std::default::Default;
141    /// # use base64::Engine;
142    /// # let docker = Docker::connect_with_http_defaults().unwrap();
143    /// use bollard_next::secret::SecretSpec;
144    ///
145    /// use base64;
146    ///
147    /// let secret_spec = SecretSpec {
148    ///     name: Some(String::from("secret-name")),
149    ///     data: Some(base64::engine::general_purpose::STANDARD.encode("secret-data")),
150    ///     ..Default::default()
151    /// };
152    ///
153    /// docker.create_secret(secret_spec);
154    /// ```
155    pub async fn create_secret(&self, secret_spec: SecretSpec) -> Result<IdResponse, Error> {
156        let url = "/secrets/create";
157
158        let req = self.build_request(
159            url,
160            Builder::new().method(hyper::Method::POST),
161            None::<String>,
162            Docker::serialize_payload(Some(secret_spec)),
163        );
164
165        self.process_into_value(req).await
166    }
167
168    /// ---
169    ///
170    /// # Inspect Secret
171    ///
172    /// Inspect a secret.
173    ///
174    /// # Arguments
175    ///
176    ///  - Secret id or name as a string slice.
177    ///
178    /// # Returns
179    ///
180    ///  - [Secret](Secret), wrapped in a Future.
181    ///
182    /// # Examples
183    ///
184    /// ```rust
185    /// # use bollard_next::Docker;
186    /// # let docker = Docker::connect_with_http_defaults().unwrap();
187    ///
188    /// docker.inspect_secret("secret-id");
189    /// docker.inspect_secret("secret-name");
190    /// ```
191    pub async fn inspect_secret(&self, secret_id: &str) -> Result<Secret, Error> {
192        let url = format!("/secrets/{secret_id}");
193
194        let req = self.build_request(
195            &url,
196            Builder::new().method(hyper::Method::GET),
197            None::<String>,
198            Ok(BodyType::Left(Full::new(Bytes::new()))),
199        );
200
201        self.process_into_value(req).await
202    }
203
204    /// ---
205    ///
206    /// # Delete Secret
207    ///
208    /// Delete a secret, fails when more than one service use that secret..
209    ///
210    /// # Arguments
211    ///
212    ///  - Secret id or name as a string slice.
213    ///
214    /// # Returns
215    ///
216    ///  - unit type `()`, wrapped in a Future.
217    ///
218    /// # Examples
219    ///
220    /// ```rust
221    /// # use bollard_next::Docker;
222    /// # let docker = Docker::connect_with_http_defaults().unwrap();
223    ///
224    /// docker.delete_secret("secret-id");
225    /// docker.delete_secret("secret-name");
226    /// ```
227    pub async fn delete_secret(&self, secret_id: &str) -> Result<(), Error> {
228        let url = format!("/secrets/{secret_id}");
229
230        let req = self.build_request(
231            &url,
232            Builder::new().method(hyper::Method::DELETE),
233            None::<String>,
234            Ok(BodyType::Left(Full::new(Bytes::new()))),
235        );
236
237        self.process_into_unit(req).await
238    }
239
240    /// ---
241    ///
242    /// # Update Secret
243    ///
244    /// Update an existing secret,
245    /// fails when more than one service use that secret or trying update data.
246    ///
247    /// # Arguments
248    ///
249    ///  - Secret id or name as a string slice.
250    ///  - [SecretSpec](SecretSpec) struct.
251    ///  - [UpdateSecretOptions](UpdateSecretOptions) struct.
252    ///
253    /// # Returns
254    ///
255    ///  - unit type `()`, wrapped in a Future.
256    ///
257    /// # Examples
258    /// ```rust
259    /// # use bollard_next::Docker;
260    /// # let docker = Docker::connect_with_http_defaults().unwrap();
261    ///
262    /// use std::collections::HashMap;
263    /// use bollard_next::secret::UpdateSecretOptions;
264    ///
265    /// let result = async move {
266    ///     let existing = docker.inspect_secret("my-secret").await?;
267    ///     let version = existing.version.unwrap().index.unwrap();
268    ///     let mut spec = existing.spec.unwrap().clone();
269    ///
270    ///     let mut labels = HashMap::new();
271    ///     labels.insert(String::from("secret-label"), String::from("label-value"));
272    ///     spec.labels = Some(labels.clone());
273    ///
274    ///     let options = UpdateSecretOptions { version };
275    ///
276    ///     docker.update_secret("my-secret", spec, options).await
277    /// };
278    /// ```
279    pub async fn update_secret(
280        &self,
281        secret_id: &str,
282        secret_spec: SecretSpec,
283        options: UpdateSecretOptions,
284    ) -> Result<(), Error> {
285        let url = format!("/secrets/{secret_id}/update");
286
287        let req = self.build_request(
288            &url,
289            Builder::new().method(hyper::Method::POST),
290            Some(options),
291            Docker::serialize_payload(Some(secret_spec)),
292        );
293
294        self.process_into_unit(req).await
295    }
296}