summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/builder.rs166
-rw-r--r--src/lib.rs1
-rw-r--r--src/rep.rs8
3 files changed, 76 insertions, 99 deletions
diff --git a/src/builder.rs b/src/builder.rs
index ba300af..05576f4 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -9,7 +9,7 @@ use std::iter::Peekable;
// Third party
use serde::Serialize;
-use serde_json::{self, map::Map, Number, Value};
+use serde_json::{self, map::Map, Value};
use url::form_urlencoded;
// Ours
@@ -335,8 +335,6 @@ impl ContainerListOptionsBuilder {
pub struct ContainerOptions {
pub name: Option<String>,
params: HashMap<&'static str, Value>,
- params_list: HashMap<&'static str, Vec<String>>,
- params_hash: HashMap<String, Vec<HashMap<String, String>>>,
}
/// Function to insert a JSON value into a tree where the desired
@@ -385,8 +383,6 @@ impl ContainerOptions {
body_members.insert("HostConfig".to_string(), Value::Object(Map::new()));
let mut body = Value::Object(body_members);
self.parse_from(&self.params, &mut body);
- self.parse_from(&self.params_list, &mut body);
- self.parse_from(&self.params_hash, &mut body);
body
}
@@ -410,23 +406,14 @@ impl ContainerOptions {
pub struct ContainerOptionsBuilder {
name: Option<String>,
params: HashMap<&'static str, Value>,
- params_list: HashMap<&'static str, Vec<String>>,
- params_hash: HashMap<String, Vec<HashMap<String, String>>>,
}
impl ContainerOptionsBuilder {
pub(crate) fn new(image: &str) -> Self {
let mut params = HashMap::new();
- let params_list = HashMap::new();
- let params_hash = HashMap::new();
params.insert("Image", Value::String(image.to_owned()));
- ContainerOptionsBuilder {
- name: None,
- params,
- params_list,
- params_hash,
- }
+ ContainerOptionsBuilder { name: None, params }
}
pub fn name(
@@ -441,12 +428,40 @@ impl ContainerOptionsBuilder {
&mut self,
volumes: Vec<&str>,
) -> &mut Self {
- for v in volumes {
- self.params_list
- .entry("HostConfig.Binds")
- .or_insert_with(Vec::new)
- .push(v.to_owned());
+ self.params.insert("HostConfig.Binds", json!(volumes));
+ self
+ }
+
+ pub fn expose(
+ &mut self,
+ srcport: u32,
+ protocol: &str,
+ hostport: u32,
+ ) -> &mut Self {
+ let mut exposedport: HashMap<String, String> = HashMap::new();
+ exposedport.insert("HostPort".to_string(), hostport.to_string());
+
+ /* The idea here is to go thought the 'old' port binds
+ * and to apply them to the local 'binding' variable,
+ * add the bind we want and replace the 'old' value */
+ let mut binding: HashMap<String, Value> = HashMap::new();
+ for (key, val) in self
+ .params
+ .get("HostConfig.PortBindings")
+ .unwrap_or(&mut json!(null))
+ .as_object()
+ .unwrap_or(&mut Map::new())
+ .iter()
+ {
+ binding.insert(key.to_string(), json!(val));
}
+ binding.insert(
+ format!("{}/{}", srcport, protocol),
+ json!(vec![exposedport]),
+ );
+
+ self.params
+ .insert("HostConfig.PortBindings", json!(binding));
self
}
@@ -454,12 +469,7 @@ impl ContainerOptionsBuilder {
&mut self,
links: Vec<&str>,
) -> &mut Self {
- for link in links {
- self.params_list
- .entry("HostConfig.Links")
- .or_insert_with(Vec::new)
- .push(link.to_owned());
- }
+ self.params.insert("HostConfig.Links", json!(links));
self
}
@@ -467,8 +477,7 @@ impl ContainerOptionsBuilder {
&mut self,
memory: u64,
) -> &mut Self {
- self.params
- .insert("HostConfig.Memory", Value::Number(Number::from(memory)));
+ self.params.insert("HostConfig.Memory", json!(memory));
self
}
@@ -476,13 +485,7 @@ impl ContainerOptionsBuilder {
&mut self,
labels: &HashMap<&str, &str>,
) -> &mut Self {
- let mut json_labels = Map::new();
- for (k, v) in labels {
- json_labels.insert(k.to_string(), Value::String(v.to_string()));
- }
-
- self.params.insert("Labels", Value::Object(json_labels));
-
+ self.params.insert("Labels", json!(labels));
self
}
@@ -490,13 +493,7 @@ impl ContainerOptionsBuilder {
&mut self,
hosts: Vec<&str>,
) -> &mut Self {
- for host in hosts {
- self.params_list
- .entry("HostConfig.ExtraHosts")
- .or_insert_with(Vec::new)
- .push(host.to_owned());
- }
-
+ self.params.insert("HostConfig.ExtraHosts", json!(hosts));
self
}
@@ -504,12 +501,7 @@ impl ContainerOptionsBuilder {
&mut self,
volumes: Vec<&str>,
) -> &mut Self {
- for volume in volumes {
- self.params_list
- .entry("HostConfig.VolumesFrom")
- .or_insert_with(Vec::new)
- .push(volume.to_owned());
- }
+ self.params.insert("HostConfig.VolumesFrom", json!(volumes));
self
}
@@ -517,10 +509,7 @@ impl ContainerOptionsBuilder {
&mut self,
network: &str,
) -> &mut Self {
- if !network.is_empty() {
- self.params
- .insert("HostConfig.NetworkMode", Value::String(network.to_owned()));
- }
+ self.params.insert("HostConfig.NetworkMode", json!(network));
self
}
@@ -528,12 +517,7 @@ impl ContainerOptionsBuilder {
&mut self,
envs: Vec<&str>,
) -> &mut Self {
- for env in envs {
- self.params_list
- .entry("Env")
- .or_insert_with(Vec::new)
- .push(env.to_owned());
- }
+ self.params.insert("Env", json!(envs));
self
}
@@ -541,12 +525,7 @@ impl ContainerOptionsBuilder {
&mut self,
cmds: Vec<&str>,
) -> &mut Self {
- for cmd in cmds {
- self.params_list
- .entry("Cmd")
- .or_insert_with(Vec::new)
- .push(cmd.to_owned());
- }
+ self.params.insert("Cmd", json!(cmds));
self
}
@@ -554,10 +533,7 @@ impl ContainerOptionsBuilder {
&mut self,
entrypoint: &str,
) -> &mut Self {
- if !entrypoint.is_empty() {
- self.params
- .insert("Entrypoint", Value::String(entrypoint.to_owned()));
- }
+ self.params.insert("Entrypoint", json!(entrypoint));
self
}
@@ -565,12 +541,7 @@ impl ContainerOptionsBuilder {
&mut self,
capabilities: Vec<&str>,
) -> &mut Self {
- for c in capabilities {
- self.params_list
- .entry("HostConfig.CapAdd")
- .or_insert_with(Vec::new)
- .push(c.to_owned());
- }
+ self.params.insert("HostConfig.CapAdd", json!(capabilities));
self
}
@@ -578,12 +549,7 @@ impl ContainerOptionsBuilder {
&mut self,
devices: Vec<HashMap<String, String>>,
) -> &mut Self {
- for d in devices {
- self.params_hash
- .entry("HostConfig.Devices".to_string())
- .or_insert_with(Vec::new)
- .push(d);
- }
+ self.params.insert("HostConfig.Devices", json!(devices));
self
}
@@ -591,12 +557,8 @@ impl ContainerOptionsBuilder {
&mut self,
log_driver: &str,
) -> &mut Self {
- if !log_driver.is_empty() {
- self.params.insert(
- "HostConfig.LogConfig.Type",
- Value::String(log_driver.to_owned()),
- );
- }
+ self.params
+ .insert("HostConfig.LogConfig.Type", json!(log_driver));
self
}
@@ -605,16 +567,12 @@ impl ContainerOptionsBuilder {
name: &str,
maximum_retry_count: u64,
) -> &mut Self {
- if !name.is_empty() {
- self.params.insert(
- "HostConfig.RestartPolicy.Name",
- Value::String(name.to_owned()),
- );
- }
+ self.params
+ .insert("HostConfig.RestartPolicy.Name", json!(name));
if name == "on-failure" {
self.params.insert(
"HostConfig.RestartPolicy.MaximumRetryCount",
- Value::Number(Number::from(maximum_retry_count)),
+ json!(maximum_retry_count),
);
}
self
@@ -624,8 +582,6 @@ impl ContainerOptionsBuilder {
ContainerOptions {
name: self.name.clone(),
params: self.params.clone(),
- params_list: self.params_list.clone(),
- params_hash: self.params_hash.clone(),
}
}
}
@@ -1273,6 +1229,26 @@ mod tests {
);
}
+ #[test]
+ fn container_options_expose() {
+ let options = ContainerOptionsBuilder::new("test_image")
+ .expose(80, "tcp", 8080)
+ .build();
+ assert_eq!(
+ r#"{"HostConfig":{"PortBindings":{"80/tcp":[{"HostPort":"8080"}]}},"Image":"test_image"}"#,
+ options.serialize().unwrap()
+ );
+ // try exposing two
+ let options = ContainerOptionsBuilder::new("test_image")
+ .expose(80, "tcp", 8080)
+ .expose(81, "tcp", 8081)
+ .build();
+ assert_eq!(
+ r#"{"HostConfig":{"PortBindings":{"80/tcp":[{"HostPort":"8080"}],"81/tcp":[{"HostPort":"8081"}]}},"Image":"test_image"}"#,
+ options.serialize().unwrap()
+ );
+ }
+
/// Test container options that are nested 3 levels deep.
#[test]
fn container_options_nested() {
diff --git a/src/lib.rs b/src/lib.rs
index e3a848c..ba807a0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,6 +29,7 @@ extern crate url;
#[macro_use]
extern crate serde_derive;
extern crate serde;
+#[macro_use]
extern crate serde_json;
extern crate tokio;
diff --git a/src/rep.rs b/src/rep.rs
index a6de7e8..bf24d0c 100644
--- a/src/rep.rs
+++ b/src/rep.rs
@@ -114,8 +114,8 @@ pub struct NetworkSettings {
pub ip_address: String,
#[serde(rename = "IPPrefixLen")]
pub ip_prefix_len: u64,
- pub mac_address: String, /* pub PortMapping: Option<???>,
- * pub Ports: Option<???> */
+ pub mac_address: String,
+ pub ports: Option<HashMap<String, Option<Vec<HashMap<String, String>>>>>,
pub networks: HashMap<String, NetworkEntry>,
}
@@ -152,7 +152,7 @@ pub struct HostConfig {
pub memory_swap: Option<i64>,
pub network_mode: String,
pub pid_mode: Option<String>,
- // pub PortBindings: ???
+ pub port_bindings: Option<HashMap<String, Vec<HashMap<String, String>>>>,
pub privileged: bool,
pub publish_all_ports: bool,
pub readonly_rootfs: Option<bool>, /* pub RestartPolicy: ???
@@ -171,7 +171,7 @@ pub struct Config {
pub domainname: String,
pub entrypoint: Option<Vec<String>>,
pub env: Option<Vec<String>>,
- // ExposedPorts
+ pub exposed_ports: Option<HashMap<String, HashMap<String, String>>>,
pub hostname: String,
pub image: String,
pub labels: Option<HashMap<String, String>>,