Pass in Network to containers
This commit is contained in:
parent
5630dd79e9
commit
820f1c3447
|
@ -4,17 +4,18 @@ use dns_test::client::{Client, Dnssec, Recurse};
|
|||
use dns_test::name_server::NameServer;
|
||||
use dns_test::record::RecordType;
|
||||
use dns_test::zone_file::Root;
|
||||
use dns_test::{Resolver, Result, TrustAnchor, FQDN};
|
||||
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
||||
|
||||
#[test]
|
||||
fn can_resolve() -> Result<()> {
|
||||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM)?;
|
||||
let network = Network::new()?;
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT, &network)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM, &network)?;
|
||||
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?;
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?, &network)?;
|
||||
nameservers_ns
|
||||
.a(root_ns.fqdn().clone(), root_ns.ipv4_addr())
|
||||
.a(com_ns.fqdn().clone(), com_ns.ipv4_addr())
|
||||
|
@ -38,10 +39,10 @@ fn can_resolve() -> Result<()> {
|
|||
eprintln!("root.zone:\n{}", root_ns.zone_file());
|
||||
|
||||
let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())];
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &TrustAnchor::empty())?;
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &TrustAnchor::empty(), &network)?;
|
||||
let resolver_ip_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::Yes,
|
||||
Dnssec::No,
|
||||
|
@ -66,10 +67,11 @@ fn can_resolve() -> Result<()> {
|
|||
fn nxdomain() -> Result<()> {
|
||||
let needle_fqdn = FQDN("unicorn.nameservers.com.")?;
|
||||
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM)?;
|
||||
let network = Network::new()?;
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT, &network)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM, &network)?;
|
||||
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?;
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?, &network)?;
|
||||
nameservers_ns
|
||||
.a(root_ns.fqdn().clone(), root_ns.ipv4_addr())
|
||||
.a(com_ns.fqdn().clone(), com_ns.ipv4_addr());
|
||||
|
@ -86,10 +88,10 @@ fn nxdomain() -> Result<()> {
|
|||
let root_ns = root_ns.start()?;
|
||||
|
||||
let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())];
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &TrustAnchor::empty())?;
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &TrustAnchor::empty(), &network)?;
|
||||
let resolver_ip_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::Yes,
|
||||
Dnssec::No,
|
||||
|
|
|
@ -4,13 +4,14 @@ use dns_test::client::{Client, Dnssec, Recurse};
|
|||
use dns_test::name_server::NameServer;
|
||||
use dns_test::record::RecordType;
|
||||
use dns_test::zone_file::Root;
|
||||
use dns_test::{Resolver, Result, TrustAnchor, FQDN};
|
||||
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
||||
|
||||
// no DS records are involved; this is a single-link chain of trust
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn can_validate_without_delegation() -> Result<()> {
|
||||
let mut ns = NameServer::new(FQDN::ROOT)?;
|
||||
let network = Network::new()?;
|
||||
let mut ns = NameServer::new(FQDN::ROOT, &network)?;
|
||||
ns.a(ns.fqdn().clone(), ns.ipv4_addr());
|
||||
let ns = ns.sign()?;
|
||||
|
||||
|
@ -26,10 +27,10 @@ fn can_validate_without_delegation() -> Result<()> {
|
|||
let roots = &[Root::new(ns.fqdn().clone(), ns.ipv4_addr())];
|
||||
|
||||
let trust_anchor = TrustAnchor::from_iter([root_ksk.clone(), root_zsk.clone()]);
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &trust_anchor)?;
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &trust_anchor, &network)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::Yes,
|
||||
Dnssec::Yes,
|
||||
|
@ -53,10 +54,11 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM)?;
|
||||
let network = Network::new()?;
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT, &network)?;
|
||||
let mut com_ns = NameServer::new(FQDN::COM, &network)?;
|
||||
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?;
|
||||
let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?, &network)?;
|
||||
nameservers_ns
|
||||
.a(root_ns.fqdn().clone(), root_ns.ipv4_addr())
|
||||
.a(com_ns.fqdn().clone(), com_ns.ipv4_addr())
|
||||
|
@ -96,10 +98,10 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||
let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())];
|
||||
|
||||
let trust_anchor = TrustAnchor::from_iter([root_ksk.clone(), root_zsk.clone()]);
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &trust_anchor)?;
|
||||
let resolver = Resolver::start(dns_test::subject(), roots, &trust_anchor, &network)?;
|
||||
let resolver_addr = resolver.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::Yes,
|
||||
Dnssec::Yes,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use core::str::FromStr;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use crate::container::Container;
|
||||
use crate::container::{Container, Network};
|
||||
use crate::record::{Record, RecordType};
|
||||
use crate::trust_anchor::TrustAnchor;
|
||||
use crate::{Error, Implementation, Result, FQDN};
|
||||
|
@ -11,9 +11,9 @@ pub struct Client {
|
|||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new() -> Result<Self> {
|
||||
pub fn new(network: &Network) -> Result<Self> {
|
||||
Ok(Self {
|
||||
inner: Container::run(Implementation::Unbound)?,
|
||||
inner: Container::run(Implementation::Unbound, network)?,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ use tempfile::{NamedTempFile, TempDir};
|
|||
|
||||
use crate::{Error, Implementation, Result};
|
||||
|
||||
pub use crate::container::network::Network;
|
||||
|
||||
pub struct Container {
|
||||
inner: Arc<Inner>,
|
||||
}
|
||||
|
@ -20,7 +22,7 @@ const PACKAGE_NAME: &str = env!("CARGO_PKG_NAME");
|
|||
|
||||
impl Container {
|
||||
/// Starts the container in a "parked" state
|
||||
pub fn run(implementation: Implementation) -> Result<Self> {
|
||||
pub fn run(implementation: Implementation, network: &Network) -> Result<Self> {
|
||||
// TODO make this configurable and support hickory & bind
|
||||
let dockerfile = implementation.dockerfile();
|
||||
let docker_build_dir = TempDir::new()?;
|
||||
|
@ -269,7 +271,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn run_works() -> Result<()> {
|
||||
let container = Container::run(Implementation::Unbound)?;
|
||||
let network = Network::new()?;
|
||||
let container = Container::run(Implementation::Unbound, &network)?;
|
||||
|
||||
let output = container.output(&["true"])?;
|
||||
assert!(output.status.success());
|
||||
|
@ -279,7 +282,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn ipv4_addr_works() -> Result<()> {
|
||||
let container = Container::run(Implementation::Unbound)?;
|
||||
let network = Network::new()?;
|
||||
let container = Container::run(Implementation::Unbound, &network)?;
|
||||
let ipv4_addr = container.ipv4_addr();
|
||||
|
||||
let output = container.output(&["ping", "-c1", &format!("{ipv4_addr}")])?;
|
||||
|
@ -290,7 +294,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn cp_works() -> Result<()> {
|
||||
let container = Container::run(Implementation::Unbound)?;
|
||||
let network = Network::new()?;
|
||||
let container = Container::run(Implementation::Unbound, &network)?;
|
||||
|
||||
let path = "/tmp/somefile";
|
||||
let contents = "hello";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::{
|
||||
process::{Command, Stdio},
|
||||
process::{Command, ExitStatus, Stdio},
|
||||
sync::atomic::{self, AtomicUsize},
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@ const NETWORK_NAME: &str = "dnssec-network";
|
|||
/// Represents a network in which to put containers into.
|
||||
pub struct Network {
|
||||
name: String,
|
||||
config: NetworkConfig,
|
||||
}
|
||||
|
||||
impl Network {
|
||||
|
@ -17,6 +18,9 @@ impl Network {
|
|||
let id = network_count();
|
||||
let network_name = format!("{NETWORK_NAME}-{id}");
|
||||
|
||||
// A network can exist, for example when a test panics
|
||||
let _ = remove_network(network_name.as_str())?;
|
||||
|
||||
let mut command = Command::new("docker");
|
||||
command
|
||||
.args(["network", "create"])
|
||||
|
@ -33,8 +37,12 @@ impl Network {
|
|||
);
|
||||
|
||||
// inspect & parse network details
|
||||
let config = get_network_config(&network_name)?;
|
||||
|
||||
Ok(Self { name: network_name })
|
||||
Ok(Self {
|
||||
name: network_name,
|
||||
config,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the name of the network.
|
||||
|
@ -49,7 +57,7 @@ pub struct NetworkConfig {
|
|||
subnet: String,
|
||||
}
|
||||
|
||||
///
|
||||
/// Return network config
|
||||
fn get_network_config(network_name: &str) -> Result<NetworkConfig> {
|
||||
let mut command = Command::new("docker");
|
||||
command
|
||||
|
@ -70,19 +78,22 @@ fn get_network_config(network_name: &str) -> Result<NetworkConfig> {
|
|||
Ok(NetworkConfig { subnet })
|
||||
}
|
||||
|
||||
/// This ensure the Docket network is deleted after the test runner process ends.
|
||||
/// This ensure the Docker 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();
|
||||
let _ = remove_network(&self.name);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_network(network_name: &str) -> Result<ExitStatus> {
|
||||
let mut command = Command::new("docker");
|
||||
command
|
||||
.args(["network", "rm", "--force", network_name])
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null());
|
||||
Ok(command.status()?)
|
||||
}
|
||||
|
||||
fn network_count() -> usize {
|
||||
static COUNT: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use core::fmt;
|
||||
use std::sync::Once;
|
||||
|
||||
pub use crate::container::Network;
|
||||
pub use crate::fqdn::FQDN;
|
||||
pub use crate::resolver::Resolver;
|
||||
pub use crate::trust_anchor::TrustAnchor;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use core::sync::atomic::{self, AtomicUsize};
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use crate::container::{Child, Container};
|
||||
use crate::container::{Child, Container, Network};
|
||||
use crate::zone_file::{self, SoaSettings, ZoneFile, DNSKEY, DS};
|
||||
use crate::{Implementation, Result, FQDN};
|
||||
|
||||
|
@ -24,7 +24,7 @@ impl<'a> NameServer<'a, Stopped> {
|
|||
/// - one SOA record, with the primary name server field set to this name server's FQDN
|
||||
/// - one NS record, with this name server's FQDN set as the only available name server for
|
||||
/// the zone
|
||||
pub fn new(zone: FQDN<'a>) -> Result<Self> {
|
||||
pub fn new(zone: FQDN<'a>, network: &Network) -> Result<Self> {
|
||||
let ns_count = ns_count();
|
||||
let nameserver = primary_ns(ns_count);
|
||||
|
||||
|
@ -42,7 +42,7 @@ impl<'a> NameServer<'a, Stopped> {
|
|||
});
|
||||
|
||||
Ok(Self {
|
||||
container: Container::run(Implementation::Unbound)?,
|
||||
container: Container::run(Implementation::Unbound, network)?,
|
||||
zone_file,
|
||||
state: Stopped,
|
||||
})
|
||||
|
@ -290,10 +290,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn simplest() -> Result<()> {
|
||||
let tld_ns = NameServer::new(FQDN::COM)?.start()?;
|
||||
let network = Network::new()?;
|
||||
let tld_ns = NameServer::new(FQDN::COM, &network)?.start()?;
|
||||
let ip_addr = tld_ns.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::No,
|
||||
Dnssec::No,
|
||||
|
@ -309,8 +310,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn with_referral() -> Result<()> {
|
||||
let network = Network::new()?;
|
||||
let expected_ip_addr = Ipv4Addr::new(172, 17, 200, 1);
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT)?;
|
||||
let mut root_ns = NameServer::new(FQDN::ROOT, &network)?;
|
||||
root_ns.referral(
|
||||
FQDN::COM,
|
||||
FQDN("primary.tld-server.com.")?,
|
||||
|
@ -322,7 +324,7 @@ mod tests {
|
|||
|
||||
let ipv4_addr = root_ns.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::No,
|
||||
Dnssec::No,
|
||||
|
@ -338,7 +340,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn signed() -> Result<()> {
|
||||
let ns = NameServer::new(FQDN::ROOT)?.sign()?;
|
||||
let network = Network::new()?;
|
||||
let ns = NameServer::new(FQDN::ROOT, &network)?.sign()?;
|
||||
|
||||
eprintln!("KSK:\n{}", ns.key_signing_key());
|
||||
eprintln!("ZSK:\n{}", ns.zone_signing_key());
|
||||
|
@ -348,7 +351,7 @@ mod tests {
|
|||
|
||||
let ns_addr = tld_ns.ipv4_addr();
|
||||
|
||||
let client = Client::new()?;
|
||||
let client = Client::new(&network)?;
|
||||
let output = client.dig(
|
||||
Recurse::No,
|
||||
Dnssec::Yes,
|
||||
|
@ -373,7 +376,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn terminate_works() -> Result<()> {
|
||||
let ns = NameServer::new(FQDN::ROOT)?.start()?;
|
||||
let network = Network::new()?;
|
||||
let ns = NameServer::new(FQDN::ROOT, &network)?.start()?;
|
||||
let logs = ns.terminate()?;
|
||||
|
||||
assert!(logs.contains("nsd starting"));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use core::fmt::Write;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use crate::container::{Child, Container};
|
||||
use crate::container::{Child, Container, Network};
|
||||
use crate::trust_anchor::TrustAnchor;
|
||||
use crate::zone_file::Root;
|
||||
use crate::{Implementation, Result};
|
||||
|
@ -23,6 +23,7 @@ impl Resolver {
|
|||
implementation: Implementation,
|
||||
roots: &[Root],
|
||||
trust_anchor: &TrustAnchor,
|
||||
network: &Network,
|
||||
) -> Result<Self> {
|
||||
const TRUST_ANCHOR_FILE: &str = "/etc/trusted-key.key";
|
||||
|
||||
|
@ -31,7 +32,7 @@ impl Resolver {
|
|||
"must configure at least one local root server"
|
||||
);
|
||||
|
||||
let container = Container::run(implementation)?;
|
||||
let container = Container::run(implementation, network)?;
|
||||
|
||||
let mut hints = String::new();
|
||||
for root in roots {
|
||||
|
@ -110,12 +111,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn terminate_works() -> Result<()> {
|
||||
let ns = NameServer::new(FQDN::ROOT)?.start()?;
|
||||
|
||||
let network = Network::new()?;
|
||||
let ns = NameServer::new(FQDN::ROOT, &network)?.start()?;
|
||||
let resolver = Resolver::start(
|
||||
Implementation::Unbound,
|
||||
&[Root::new(ns.fqdn().clone(), ns.ipv4_addr())],
|
||||
&TrustAnchor::empty(),
|
||||
&network,
|
||||
)?;
|
||||
let logs = resolver.terminate()?;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user