diff options
Diffstat (limited to 'src/docker.rs')
-rw-r--r-- | src/docker.rs | 147 |
1 files changed, 145 insertions, 2 deletions
diff --git a/src/docker.rs b/src/docker.rs index d3faa82..c44356e 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -2,15 +2,15 @@ //! //! API Reference: <https://docs.docker.com/engine/api/v1.41/> -use std::{env, io, path::Path}; +use std::{collections::HashMap, env, io, path::Path}; use futures_util::{stream::Stream, TryStreamExt}; use hyper::{client::HttpConnector, Body, Client, Method}; use mime::Mime; use serde_json::Value; +use url::form_urlencoded; use crate::{ - builder::EventsOptions, container::Containers, errors::{Error, Result}, image::Images, @@ -399,6 +399,149 @@ impl Default for Docker { } } +/// Options for filtering streams of Docker events +#[derive(Default, Debug)] +pub struct EventsOptions { + params: HashMap<&'static str, String>, +} + +impl EventsOptions { + pub fn builder() -> EventsOptionsBuilder { + EventsOptionsBuilder::default() + } + + /// serialize options as a string. returns None if no options are defined + pub fn serialize(&self) -> Option<String> { + if self.params.is_empty() { + None + } else { + Some( + form_urlencoded::Serializer::new(String::new()) + .extend_pairs(&self.params) + .finish(), + ) + } + } +} + +#[derive(Copy, Clone)] +pub enum EventFilterType { + Container, + Image, + Volume, + Network, + Daemon, +} + +fn event_filter_type_to_string(filter: EventFilterType) -> &'static str { + match filter { + EventFilterType::Container => "container", + EventFilterType::Image => "image", + EventFilterType::Volume => "volume", + EventFilterType::Network => "network", + EventFilterType::Daemon => "daemon", + } +} + +/// Filter options for image listings +pub enum EventFilter { + Container(String), + Event(String), + Image(String), + Label(String), + Type(EventFilterType), + Volume(String), + Network(String), + Daemon(String), +} + +/// Builder interface for `EventOptions` +#[derive(Default)] +pub struct EventsOptionsBuilder { + params: HashMap<&'static str, String>, + events: Vec<String>, + containers: Vec<String>, + images: Vec<String>, + labels: Vec<String>, + volumes: Vec<String>, + networks: Vec<String>, + daemons: Vec<String>, + types: Vec<String>, +} + +impl EventsOptionsBuilder { + /// Filter events since a given timestamp + pub fn since( + &mut self, + ts: &u64, + ) -> &mut Self { + self.params.insert("since", ts.to_string()); + self + } + + /// Filter events until a given timestamp + pub fn until( + &mut self, + ts: &u64, + ) -> &mut Self { + self.params.insert("until", ts.to_string()); + self + } + + pub fn filter( + &mut self, + filters: Vec<EventFilter>, + ) -> &mut Self { + let mut params = HashMap::new(); + for f in filters { + match f { + EventFilter::Container(n) => { + self.containers.push(n); + params.insert("container", self.containers.clone()) + } + EventFilter::Event(n) => { + self.events.push(n); + params.insert("event", self.events.clone()) + } + EventFilter::Image(n) => { + self.images.push(n); + params.insert("image", self.images.clone()) + } + EventFilter::Label(n) => { + self.labels.push(n); + params.insert("label", self.labels.clone()) + } + EventFilter::Volume(n) => { + self.volumes.push(n); + params.insert("volume", self.volumes.clone()) + } + EventFilter::Network(n) => { + self.networks.push(n); + params.insert("network", self.networks.clone()) + } + EventFilter::Daemon(n) => { + self.daemons.push(n); + params.insert("daemon", self.daemons.clone()) + } + EventFilter::Type(n) => { + let event_type = event_filter_type_to_string(n).to_string(); + self.types.push(event_type); + params.insert("type", self.types.clone()) + } + }; + } + self.params + .insert("filters", serde_json::to_string(¶ms).unwrap()); + self + } + + pub fn build(&self) -> EventsOptions { + EventsOptions { + params: self.params.clone(), + } + } +} + #[cfg(test)] mod tests { #[cfg(feature = "unix-socket")] |