From 00e0e7479e63dd9f19952c6584ec6dbc6f57cce1 Mon Sep 17 00:00:00 2001 From: Tamipes Date: Wed, 3 Jun 2026 23:25:54 +0200 Subject: [PATCH] feat: handle internall address differntly if running inside a cluster --- kube/roles.yaml | 2 +- src/kube_cache.rs | 78 +++++++++++++++++++++++++++++++++++------------ src/mc_server.rs | 7 ++--- 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/kube/roles.yaml b/kube/roles.yaml index 09111bf..0c90cc6 100644 --- a/kube/roles.yaml +++ b/kube/roles.yaml @@ -47,7 +47,7 @@ spec: serviceAccountName: minecraft-ingress containers: - name: minecraft-ingress - image: git.tami.moe/tamipes/minecraft-ingress:latest + image: git.tami.moe/tamipes/minecraft-ingress:testing env: - name: FILTER_CONN value: '(addr == "87.229.85.222") || (addr == "") || (addr == "ogmur.xyz") || (addr == "@mat:matdoes.dev (hi honeypots) ") || (addr == "@mat:matdoes.dev ") || (addr == "slowstack.tv")' diff --git a/src/kube_cache.rs b/src/kube_cache.rs index ea76a90..9b9e671 100644 --- a/src/kube_cache.rs +++ b/src/kube_cache.rs @@ -1,6 +1,9 @@ use std::{collections::HashMap, fmt, sync::Arc, time::Duration}; -use k8s_openapi::api::{apps::v1::Deployment, core::v1::Service}; +use k8s_openapi::{ + api::{apps::v1::Deployment, core::v1::Service}, + apimachinery::pkg::util::intstr::IntOrString, +}; use kube::{ api::{ListParams, ObjectList, Patch, PatchParams}, runtime::reflector::Lookup, @@ -25,11 +28,16 @@ use crate::{ pub struct KubeCache { deployments: Api, services: Api, + in_cluster: bool, } impl KubeCache { /// This initializes the creation of a "kubernetes client" /// and if it is not possible returns a None. pub async fn create() -> Option { + let in_cluster = match std::env::var("KUBERNETES_SERVICE_HOST") { + Ok(x) => true, + Err(e) => false, + }; let client = Client::try_default().await.unwrap(); let deployments: Api = Api::default_namespaced(client.clone()); @@ -38,6 +46,7 @@ impl KubeCache { return Some(KubeCache { deployments, services, + in_cluster, }); } async fn get_dep(&self, name: &str) -> Result { @@ -63,10 +72,17 @@ impl KubeCache { Some(result.name()?.to_string()) } - pub async fn query_srv_addr(&self, addr: &str, port: &str) -> Option { + pub async fn query_srv(&self, addr: &str, port: &str) -> Option { let deploys = self.get_srvs().await; - let result = deploys.iter().find(|x| filter_label_value(x, addr, port))?; - Some(result.name()?.to_string()) + let result = deploys.into_iter().find(|x| { + let in_cluster = match x.spec.as_ref().unwrap().type_.as_ref() { + Some(t) => t == "ClusterIP", + None => false, + }; + let incorrect_type = in_cluster ^ self.in_cluster; + !incorrect_type && filter_label_value(&x, addr, port) + })?; + Some(result) } async fn set_dep_scale(&self, name: &str, num: i32) -> Result { @@ -100,11 +116,11 @@ impl MinecraftAPI for McApi { )) } }; - let srv_name = match self.cache.query_srv_addr(&addr, &port).await { + let service = match self.cache.query_srv(&addr, &port).await { Some(x) => x, None => { return Err(OpaqueError::create_with_kind( - "Failed to find service name by addr", + "Failed to find service by addr and port", "SrvNameLookupFailed", )) } @@ -116,20 +132,46 @@ impl MinecraftAPI for McApi { x.to_string() ) })?; - let service = self.cache.get_srv(&srv_name).await.map_err(|x| { - format!( - "Failed to query cache for service with dep_name err:{}", - x.to_string() - ) - })?; tracing::debug!("found kubernetes deployment & service"); + let service_port_spec = service.clone().spec.unwrap().ports.unwrap(); + let port = service_port_spec + .iter() + .find(|x| x.name.clone().unwrap() == "mc-router") + .ok_or(OpaqueError::create( + "Could not find \"mc-router\" nodePort for server", + ))?; + let port_string; + let inter_addr = match self.cache.in_cluster { + false => { + let node_port = port + .node_port + .map(|x| x.to_string()) + .ok_or(OpaqueError::create("Could not map nodePort to port string"))?; + port_string = node_port.clone(); + format!("localhost:{}", node_port) + } + true => { + let target_port = port.port; + let a = format!( + "{}.default.svc.cluster.local:{}", + service + .name() + .ok_or("Could not get name of ClusterIP service")?, + target_port + ); + port_string = a.clone(); + a + } + }; + tracing::info!(inter_addr = inter_addr); return Ok(Server { dep: deployment, srv: service, server_addr: addr.to_string(), - server_port: port.to_string(), + server_port: port_string, cache: self.cache.clone(), + inter_addr: inter_addr, }); } @@ -223,6 +265,7 @@ pub struct Server { server_addr: String, server_port: String, cache: KubeCache, + inter_addr: String, } impl fmt::Debug for Server { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -308,8 +351,8 @@ impl MinecraftServerHandle for Server { } } - fn get_internal_address(&self) -> Option { - Some(format!("localhost:{}", self.get_internal_port()?)) + fn get_internal_address(&self) -> &str { + self.inter_addr.as_str() } fn get_addr(&self) -> Option { @@ -358,11 +401,6 @@ impl MinecraftServerHandle for Server { } } - fn get_internal_port(&self) -> Option { - let a = self.srv.clone().spec.unwrap().ports.unwrap(); - let port = a.iter().find(|x| x.name.clone().unwrap() == "mc-router")?; - port.node_port.map(|x| x.to_string()) - } fn get_port(&self) -> Option { Some(self.server_port.clone()) } diff --git a/src/mc_server.rs b/src/mc_server.rs index 03b6a9d..88e6e8b 100644 --- a/src/mc_server.rs +++ b/src/mc_server.rs @@ -64,16 +64,13 @@ pub trait MinecraftServerHandle: Clone { async fn start(&self) -> Result<(), OpaqueError>; async fn stop(&self) -> Result<(), OpaqueError>; async fn query_status(&self) -> Result; - fn get_internal_address(&self) -> Option; - fn get_internal_port(&self) -> Option; + fn get_internal_address(&self) -> &str; fn get_addr(&self) -> Option; fn get_port(&self) -> Option; fn get_motd(&self) -> Option; async fn query_server_connectable(&self) -> Result { - let address = self - .get_internal_address() - .ok_or_else(|| "failed to get internal address from server")?; + let address = self.get_internal_address(); let server_stream = TcpStream::connect(address) .await .map_err(|_| "failed to connect to minecraft server")?;