Add Network types
Creates & removes the Docker network & reads in the allocated subnet mask.
This commit is contained in:
parent
f690522111
commit
5630dd79e9
@ -1,3 +1,5 @@
|
|||||||
|
mod network;
|
||||||
|
|
||||||
use core::str;
|
use core::str;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
109
packages/dns-test/src/container/network.rs
Normal file
109
packages/dns-test/src/container/network.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
use std::{
|
||||||
|
process::{Command, Stdio},
|
||||||
|
sync::atomic::{self, AtomicUsize},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
|
const NETWORK_NAME: &str = "dnssec-network";
|
||||||
|
|
||||||
|
/// Represents a network in which to put containers into.
|
||||||
|
pub struct Network {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Network {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let id = network_count();
|
||||||
|
let network_name = format!("{NETWORK_NAME}-{id}");
|
||||||
|
|
||||||
|
let mut command = Command::new("docker");
|
||||||
|
command
|
||||||
|
.args(["network", "create"])
|
||||||
|
.args(["--internal"])
|
||||||
|
.arg(&network_name);
|
||||||
|
|
||||||
|
// create network
|
||||||
|
let output = command.output().unwrap();
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
assert!(
|
||||||
|
output.status.success(),
|
||||||
|
"--- STDOUT ---\n{stdout}\n--- STDERR ---\n{stderr}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// inspect & parse network details
|
||||||
|
|
||||||
|
Ok(Self { name: network_name })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the name of the network.
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
self.name.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Collects all important configs.
|
||||||
|
pub struct NetworkConfig {
|
||||||
|
/// The CIDR subnet mask, e.g. "172.21.0.0/16"
|
||||||
|
subnet: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
fn get_network_config(network_name: &str) -> Result<NetworkConfig> {
|
||||||
|
let mut command = Command::new("docker");
|
||||||
|
command
|
||||||
|
.args([
|
||||||
|
"network",
|
||||||
|
"inspect",
|
||||||
|
"-f",
|
||||||
|
"{{range .IPAM.Config}}{{.Subnet}}{{end}}",
|
||||||
|
])
|
||||||
|
.arg(network_name);
|
||||||
|
|
||||||
|
let output = command.output()?;
|
||||||
|
if !output.status.success() {
|
||||||
|
return Err(format!("{command:?} failed").into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let subnet = std::str::from_utf8(&output.stdout)?.trim().to_string();
|
||||||
|
Ok(NetworkConfig { subnet })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This ensure the Docket network is deleted after the test runner process ends.
|
||||||
|
impl Drop for Network {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Remove the network
|
||||||
|
// TODO check if all containers need to disconnect first
|
||||||
|
let _ = Command::new("docker")
|
||||||
|
.args(["network", "rm", "--force", self.name.as_str()])
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.status();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn network_count() -> usize {
|
||||||
|
static COUNT: AtomicUsize = AtomicUsize::new(1);
|
||||||
|
|
||||||
|
COUNT.fetch_add(1, atomic::Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_works() -> Result<()> {
|
||||||
|
assert!(Network::new().is_ok());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn network_subnet_works() -> Result<()> {
|
||||||
|
let network = Network::new().expect("Failed to create network");
|
||||||
|
let config = get_network_config(network.name());
|
||||||
|
assert!(config.is_ok());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user