diff --git a/src/proxy.rs b/src/proxy.rs index 4784a18..1f270fa 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -57,7 +57,22 @@ impl ActiveInstances { return Some(ip); } - let addr = if ServiceType::from_str(name).is_ok() { + let addr = self.resolve_addr(name).await?; + + println!("{name} => {addr}"); + self.known.lock().unwrap().insert(name.into(), addr); + Some(addr) + } + + async fn resolve_addr(&self, name: &str) -> Option { + // instance + if let Ok(cloud) = Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config).await + { + return Some(SocketAddr::new(cloud.ip?, 80)); + } + + // service + if ServiceType::from_str(name).is_ok() { let cloud = self.last()?; let service = cloud.services().find(|service| service.name() == name)?; let ip = service @@ -65,42 +80,35 @@ impl ActiveInstances { .await .ok()? .next()?; - SocketAddr::new(ip, service.proxy_port()) - } else { - match name.matches('-').count() { - // instance - 1 => SocketAddr::new( - Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config) - .await - .ok()? - .ip?, - 80, - ), - // service with instance - 2.. => { - let service_name = name.splitn(3, '-').last()?; - let name = &name[0..(name.len() - service_name.len() - 1)]; - let cloud = Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config) - .await - .ok()?; - let service = cloud - .services() - .find(|service| service.name() == service_name)?; - let ip = service - .get_ips(&self.docker, &cloud.id) - .await - .ok()? - .next()?; - SocketAddr::new(ip, service.proxy_port()) - } - _ => return None, + return Some(SocketAddr::new(ip, service.proxy_port())); + } + + // instance-service + for (pos, _) in name.match_indices('-') { + let instance_name = &name[..pos]; + let service_name = &name[pos + 1..]; + if ServiceType::from_str(service_name).is_err() { + continue; } - }; - - println!("{name} => {addr}"); - - self.known.lock().unwrap().insert(name.into(), addr); - Some(addr) + let cloud = + match Cloud::get_by_filter(&self.docker, Some(instance_name.into()), &self.config) + .await + { + Ok(cloud) => cloud, + Err(_) => continue, + }; + let service = match cloud.services().find(|s| s.name() == service_name) { + Some(service) => service, + None => continue, + }; + let ip = service + .get_ips(&self.docker, &cloud.id) + .await + .ok()? + .next()?; + return Some(SocketAddr::new(ip, service.proxy_port())); + } + None } pub fn last_addr(&self) -> Option {