use crate::docker::BodyType;
pub use crate::models::*;
use super::Docker;
use crate::auth::{DockerCredentials, DockerCredentialsHeader};
use crate::errors::Error;
use bytes::Bytes;
use http::header::CONTENT_TYPE;
use http::request::Builder;
use http::Method;
use http_body_util::Full;
use serde_derive::Serialize;
use std::{collections::HashMap, hash::Hash};
#[derive(Debug, Clone, Default, PartialEq, Serialize)]
pub struct ListServicesOptions<T>
where
T: Into<String> + Eq + Hash + serde::ser::Serialize,
{
#[serde(serialize_with = "crate::docker::serialize_as_json")]
pub filters: HashMap<T, Vec<T>>,
pub status: bool,
}
#[derive(Debug, Copy, Clone, Default, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InspectServiceOptions {
pub insert_defaults: bool,
}
#[derive(Debug, Copy, Clone, Default, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdateServiceOptions {
pub version: u64,
#[serde(serialize_with = "serialize_registry_auth_from")]
pub registry_auth_from: bool,
#[serde(serialize_with = "serialize_rollback")]
pub rollback: bool,
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn serialize_registry_auth_from<S>(
registry_auth_from: &bool,
s: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
s.serialize_str(if *registry_auth_from {
"previous-spec"
} else {
"spec"
})
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn serialize_rollback<S>(rollback: &bool, s: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
s.serialize_str(if *rollback { "previous" } else { "" })
}
impl Docker {
pub async fn list_services<T>(
&self,
options: Option<ListServicesOptions<T>>,
) -> Result<Vec<Service>, Error>
where
T: Into<String> + Eq + Hash + serde::ser::Serialize,
{
let url = "/services";
let req = self.build_request(
url,
Builder::new().method(hyper::Method::GET),
options,
Ok(BodyType::Left(Full::new(Bytes::new()))),
);
self.process_into_value(req).await
}
pub async fn create_service(
&self,
service_spec: ServiceSpec,
credentials: Option<DockerCredentials>,
) -> Result<ServiceCreateResponse, Error> {
let url = "/services/create";
let req = self.build_request_with_registry_auth(
url,
Builder::new()
.method(Method::POST)
.header(CONTENT_TYPE, "application/json"),
None::<String>,
Docker::serialize_payload(Some(service_spec)),
DockerCredentialsHeader::Auth(credentials),
);
self.process_into_value(req).await
}
pub async fn inspect_service(
&self,
service_name: &str,
options: Option<InspectServiceOptions>,
) -> Result<Service, Error> {
let url = format!("/services/{service_name}");
let req = self.build_request(
&url,
Builder::new().method(hyper::Method::GET),
options,
Ok(BodyType::Left(Full::new(Bytes::new()))),
);
self.process_into_value(req).await
}
pub async fn delete_service(&self, service_name: &str) -> Result<(), Error> {
let url = format!("/services/{service_name}");
let req = self.build_request(
&url,
Builder::new().method(hyper::Method::DELETE),
None::<String>,
Ok(BodyType::Left(Full::new(Bytes::new()))),
);
self.process_into_unit(req).await
}
pub async fn update_service(
&self,
service_name: &str,
service_spec: ServiceSpec,
options: UpdateServiceOptions,
credentials: Option<DockerCredentials>,
) -> Result<ServiceUpdateResponse, Error> {
let url = format!("/services/{service_name}/update");
let req = self.build_request_with_registry_auth(
&url,
Builder::new()
.method(Method::POST)
.header(CONTENT_TYPE, "application/json"),
Some(options),
Docker::serialize_payload(Some(service_spec)),
DockerCredentialsHeader::Auth(credentials),
);
self.process_into_value(req).await
}
}