// Ordinary settings:
pub addrs: Vec<IpAddr>,
pub vnetwork: Vec<IpNet>,
- pub vaddr: Vec<IpAddr>,
+ pub vaddr: IpAddr,
pub vrelay: IpAddr,
pub port: u16,
pub mtu: u32,
impl InstanceConfig {
#[throws(AE)]
- fn complete(&self) {
-
+ fn complete(&mut self, end: LinkEnd) {
+ let mut vhosts = self.vnetwork.iter()
+ .map(|n| n.hosts()).flatten()
+ .filter({ let vaddr = self.vaddr; move |v| v != &vaddr });
+
+ if self.vaddr.is_unspecified() {
+ self.vaddr = vhosts.next().ok_or_else(
+ || anyhow!("vnetwork too small to generate vaddrr")
+ )?;
+ }
+ if self.vrelay.is_unspecified() {
+ self.vrelay = vhosts.next().ok_or_else(
+ || anyhow!("vnetwork too small to generate vrelay")
+ )?;
+ }
+
+ match end {
+ LinkEnd::Client => {
+ if &self.url == &default::<Uri>() {
+ let addr = self.addrs.get(0).ok_or_else(
+ || anyhow!("client needs addrs or url set")
+ )?;
+ self.url = format!(
+ "http://{}{}/",
+ match addr {
+ IpAddr::V4(a) => format!("{}", a),
+ IpAddr::V6(a) => format!("[{}]", a),
+ },
+ match self.port {
+ 80 => format!(""),
+ p => format!(":{}", p),
+ })
+ .parse().unwrap()
+ }
+ },
+
+ LinkEnd::Server => {
+ if self.addrs.is_empty() {
+ throw!(anyhow!("missing 'addrs' setting"))
+ }
+ },
+ }
}
}
],
};
- let ic = InstanceConfig::resolve_instance(&rctx)
+ let mut ic = InstanceConfig::resolve_instance(&rctx)
.with_context(|| format!(r#"resolve config for "{:?}""#, &link))?;
- ic.complete()
+ ic.complete(end)
.with_context(|| format!(r#"complete config for "{:?}""#, &link))?;
ics.push(ic);