mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 17:14:08 +02:00
allow bare-service proxy hosts
This commit is contained in:
parent
8e79e997a8
commit
fdc821cb93
2 changed files with 58 additions and 24 deletions
|
|
@ -218,7 +218,7 @@ fn test_option_parse() {
|
|||
);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Cloud {
|
||||
pub id: String,
|
||||
pub network: String,
|
||||
|
|
@ -851,3 +851,9 @@ impl Cloud {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Cloud {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
|
|
|||
62
src/proxy.rs
62
src/proxy.rs
|
|
@ -1,4 +1,4 @@
|
|||
use crate::service::ServiceTrait;
|
||||
use crate::service::{ServiceTrait, ServiceType};
|
||||
use crate::Result;
|
||||
use crate::{Cloud, HazeConfig};
|
||||
use axum::http::header::HOST;
|
||||
|
|
@ -18,6 +18,7 @@ use std::fs::{create_dir_all, set_permissions};
|
|||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tokio::net::UnixListener;
|
||||
|
|
@ -28,7 +29,7 @@ use tracing::{debug, error, info};
|
|||
|
||||
struct ActiveInstances {
|
||||
known: Mutex<HashMap<String, SocketAddr>>,
|
||||
last: Mutex<Option<SocketAddr>>,
|
||||
last: Mutex<Option<Cloud>>,
|
||||
docker: Docker,
|
||||
config: HazeConfig,
|
||||
}
|
||||
|
|
@ -48,8 +49,27 @@ impl ActiveInstances {
|
|||
return Some(ip);
|
||||
}
|
||||
|
||||
// service proxy
|
||||
let addr = if name.matches('-').count() == 2 {
|
||||
let addr = if ServiceType::from_str(name).is_ok() {
|
||||
let cloud = self.last()?;
|
||||
let service = cloud.services().find(|service| service.name() == name)?;
|
||||
let ip = service
|
||||
.get_ips(&self.docker, &cloud.id)
|
||||
.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 (name, service_name) = name.rsplit_once('-').unwrap();
|
||||
let cloud = Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config)
|
||||
.await
|
||||
|
|
@ -63,14 +83,9 @@ impl ActiveInstances {
|
|||
.ok()?
|
||||
.next()?;
|
||||
SocketAddr::new(ip, service.proxy_port())
|
||||
} else {
|
||||
SocketAddr::new(
|
||||
Cloud::get_by_filter(&self.docker, Some(name.into()), &self.config)
|
||||
.await
|
||||
.ok()?
|
||||
.ip?,
|
||||
80,
|
||||
)
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
|
||||
println!("{name} => {addr}");
|
||||
|
|
@ -79,18 +94,31 @@ impl ActiveInstances {
|
|||
Some(addr)
|
||||
}
|
||||
|
||||
pub fn last(&self) -> Option<SocketAddr> {
|
||||
*self.last.lock().unwrap()
|
||||
pub fn last_addr(&self) -> Option<SocketAddr> {
|
||||
self.last
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.and_then(|cloud| Some(SocketAddr::new(cloud.ip?, 80)))
|
||||
}
|
||||
|
||||
pub fn last(&self) -> Option<Cloud> {
|
||||
self.last.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
async fn update_last(&self) {
|
||||
let last = Cloud::get_by_filter(&self.docker, None, &self.config)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|cloud| Some(SocketAddr::new(cloud.ip?, 80)));
|
||||
.ok();
|
||||
let mut old = self.last.lock().unwrap();
|
||||
if old.as_ref() != last.as_ref() {
|
||||
info!(instance = ?last, "Found new instance");
|
||||
|
||||
// remove cached base-service mappings
|
||||
self.known
|
||||
.lock()
|
||||
.unwrap()
|
||||
.retain(|key, _| ServiceType::from_str(key).is_err());
|
||||
*old = last;
|
||||
}
|
||||
}
|
||||
|
|
@ -181,7 +209,7 @@ async fn get_remote(
|
|||
};
|
||||
let ip = if host == base_address {
|
||||
instances
|
||||
.last()
|
||||
.last_addr()
|
||||
.ok_or_else(|| String::from("No running instance known"))
|
||||
} else {
|
||||
let requested_instance = host.split('.').next().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue