diff --git a/operator/README.md b/operator/README.md index e3212a9..2424ddd 100644 --- a/operator/README.md +++ b/operator/README.md @@ -4,12 +4,12 @@ This operator allows demeter to run and expose ogmios ## Environment -| Key | Value | -| ------------- | ------------ | -| ADDR | 0.0.0.0:5000 | -| DNS_ZONE | demeter.run | -| INGRESS_CLASS | ogmios-v1 | -| API_KEY_SALT | ogmios-salt | +| Key | Value | +| -------------- | ------------ | +| ADDR | 0.0.0.0:5000 | +| DNS_ZONE | demeter.run | +| EXTENSION_NAME | ogmios-m1 | +| API_KEY_SALT | ogmios-salt | ## Commands diff --git a/operator/src/config.rs b/operator/src/config.rs index 85ebd52..5f095cd 100644 --- a/operator/src/config.rs +++ b/operator/src/config.rs @@ -12,7 +12,7 @@ pub fn get_config() -> &'static Config { #[derive(Debug, Clone)] pub struct Config { pub dns_zone: String, - pub ingress_class: String, + pub extension_name: String, pub api_key_salt: String, pub dcu_per_frame: HashMap, pub metrics_delay: Duration, @@ -22,7 +22,7 @@ pub struct Config { impl Config { pub fn from_env() -> Self { let dns_zone = env::var("DNS_ZONE").unwrap_or("demeter.run".into()); - let ingress_class = env::var("INGRESS_CLASS").unwrap_or("ogmios-m1".into()); + let extension_name = env::var("EXTENSION_NAME").unwrap_or("ogmios-m1".into()); let api_key_salt = env::var("API_KEY_SALT").unwrap_or("ogmios-salt".into()); let dcu_per_frame = env::var("DCU_PER_FRAME") .expect("DCU_PER_FRAME must be set") @@ -47,7 +47,7 @@ impl Config { Self { dns_zone, - ingress_class, + extension_name, api_key_salt, dcu_per_frame, metrics_delay, diff --git a/operator/src/utils.rs b/operator/src/utils.rs index 762450f..c6dcd32 100644 --- a/operator/src/utils.rs +++ b/operator/src/utils.rs @@ -29,11 +29,11 @@ pub async fn patch_resource_status( pub fn build_hostname(network: &Network, version: &u8, key: &str) -> (String, String) { let config = get_config(); - let ingress_class = &config.ingress_class; + let extension_name = &config.extension_name; let dns_zone = &config.dns_zone; - let hostname = format!("{network}-v{version}.{ingress_class}.{dns_zone}"); - let hostname_key = format!("{key}.{network}-v{version}.{ingress_class}.{dns_zone}"); + let hostname = format!("{network}-v{version}.{extension_name}.{dns_zone}"); + let hostname_key = format!("{key}.{network}-v{version}.{extension_name}.{dns_zone}"); (hostname, hostname_key) } diff --git a/proxy/src/proxy.rs b/proxy/src/proxy.rs index 0d7385c..976e2a3 100644 --- a/proxy/src/proxy.rs +++ b/proxy/src/proxy.rs @@ -6,7 +6,7 @@ use hyper::header::{ HeaderValue, CONNECTION, HOST, SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_KEY, UPGRADE, }; use hyper::service::service_fn; -use hyper::{Request, Response, StatusCode}; +use hyper::{Method, Request, Response, StatusCode}; use hyper_util::rt::{TokioExecutor, TokioIo}; use hyper_util::server::conn::auto::Builder; use rustls::ServerConfig; @@ -94,31 +94,43 @@ async fn handle( mut hyper_req: Request, rw_state: Arc>, ) -> Result { - let state = rw_state.read().await.clone(); - let proxy_req = ProxyRequest::new(&mut hyper_req, &state); + match (hyper_req.method(), hyper_req.uri().path()) { + (&Method::GET, "/healthz") => handle_healthz().await, + _ => { + let state = rw_state.read().await.clone(); + let proxy_req_result = ProxyRequest::new(&mut hyper_req, &state); + if proxy_req_result.is_none() { + return Ok(Response::builder() + .status(StatusCode::BAD_GATEWAY) + .body(full("Invalid hostname")) + .unwrap()); + } - if proxy_req.consumer.is_none() { - return Ok(Response::builder() - .status(StatusCode::UNAUTHORIZED) - .body(full("Unauthorized")) - .unwrap()); - } + let proxy_req = proxy_req_result.unwrap(); + if proxy_req.consumer.is_none() { + return Ok(Response::builder() + .status(StatusCode::UNAUTHORIZED) + .body(full("Unauthorized")) + .unwrap()); + } - let response_result = match proxy_req.protocol { - Protocol::Http => handle_http(hyper_req, &proxy_req).await, - Protocol::Websocket => handle_websocket(hyper_req, &proxy_req, rw_state).await, - }; + let response_result = match proxy_req.protocol { + Protocol::Http => handle_http(hyper_req, &proxy_req).await, + Protocol::Websocket => handle_websocket(hyper_req, &proxy_req, rw_state).await, + }; - match &response_result { - Ok(response) => { - state - .metrics - .count_http_total_request(&proxy_req, response.status()); - } - Err(_) => todo!("send error to prometheus"), - }; + match &response_result { + Ok(response) => { + state + .metrics + .count_http_total_request(&proxy_req, response.status()); + } + Err(_) => todo!("send error to prometheus"), + }; - response_result + response_result + } + } } async fn handle_http( @@ -204,6 +216,13 @@ async fn handle_websocket( Ok(res) } +async fn handle_healthz() -> Result { + Ok(Response::builder() + .status(StatusCode::OK) + .body(full("pong")) + .unwrap()) +} + #[derive(Debug, Clone)] pub enum Protocol { Http, @@ -227,13 +246,13 @@ pub struct ProxyRequest { pub protocol: Protocol, } impl ProxyRequest { - pub fn new(hyper_req: &mut Request, state: &State) -> Self { - let mut host = get_header(hyper_req, HOST.as_str()).unwrap(); + pub fn new(hyper_req: &mut Request, state: &State) -> Option { + let mut host = get_header(hyper_req, HOST.as_str())?; let host_regex = host.clone(); - let captures = state.host_regex.captures(&host_regex).unwrap(); - let network = captures.get(2).unwrap().as_str().to_string(); - let version = captures.get(3).unwrap().as_str().to_string(); + let captures = state.host_regex.captures(&host_regex)?; + let network = captures.get(2)?.as_str().to_string(); + let version = captures.get(3)?.as_str().to_string(); let instance = format!("ogmios-{network}-{version}:{}", state.config.ogmios_port); let namespace = state.config.proxy_namespace.clone(); @@ -259,13 +278,13 @@ impl ProxyRequest { let token = get_header(hyper_req, DMTR_API_KEY).unwrap_or_default(); let consumer = state.get_auth_token(&network, &version, &token); - Self { + Some(Self { namespace, instance, consumer, protocol, host, - } + }) } }