From 3aaeaacf8ae98f8b00d64816ac6fafeb58c70da9 Mon Sep 17 00:00:00 2001 From: RWDai <27391645+RWDai@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:48:33 +0800 Subject: [PATCH] update --- admin/src/api/backend_api.rs | 3 ++- admin/src/api/dashboard_api.rs | 11 ++++++++++- admin/src/model/query_dto.rs | 3 +++ admin/src/model/vo_converter/http_route_conv.rs | 14 ++++++++------ admin/src/model/vo_converter/plugin_vo_conv.rs | 4 ++-- admin/src/service/backend_ref_service.rs | 6 ++++-- admin/src/service/route_service.rs | 15 +++++++++++++++ .../src/converter/http_route_k8s_conv.rs | 10 +++++++--- kernel-common/src/inner_model/http_route.rs | 2 ++ 9 files changed, 53 insertions(+), 15 deletions(-) diff --git a/admin/src/api/backend_api.rs b/admin/src/api/backend_api.rs index 0f529ab3..09364721 100644 --- a/admin/src/api/backend_api.rs +++ b/admin/src/api/backend_api.rs @@ -15,13 +15,14 @@ pub struct BackendApi; impl BackendApi { /// Get Backend List #[oai(path = "/", method = "get")] - async fn list(&self, names: Query>, namespace: Query>, session: &Session) -> TardisApiResult> { + async fn list(&self, names: Query>, namespace: Query>, hosts: Query>, session: &Session) -> TardisApiResult> { let client_name = &super::get_instance_name(session).await?; let result = BackendRefVoService::list( client_name, BackendRefQueryDto { names: names.0.map(|n| n.split(',').map(|n| n.to_string()).collect()), namespace: namespace.0, + hosts: hosts.0.map(|n| n.split(',').map(|n| n.to_string()).collect()), } .to_instance()?, ) diff --git a/admin/src/api/dashboard_api.rs b/admin/src/api/dashboard_api.rs index 2814300b..b023d61b 100644 --- a/admin/src/api/dashboard_api.rs +++ b/admin/src/api/dashboard_api.rs @@ -22,7 +22,16 @@ impl DashboardApi { async fn statistics(&self, session: &Session) -> TardisApiResult { let client_name = &super::get_instance_name(session).await?; TardisResp::ok(Statistics { - backend_count: BackendRefVoService::list(client_name, BackendRefQueryInst { names: None, namespace: None }).await?.len() as i64, + backend_count: BackendRefVoService::list( + client_name, + BackendRefQueryInst { + names: None, + namespace: None, + hosts: None, + }, + ) + .await? + .len() as i64, gateway_count: GatewayVoService::list( client_name, GatewayQueryInst { diff --git a/admin/src/model/query_dto.rs b/admin/src/model/query_dto.rs index a394b167..48c4b8d1 100644 --- a/admin/src/model/query_dto.rs +++ b/admin/src/model/query_dto.rs @@ -12,6 +12,7 @@ pub trait ToInstance { pub struct BackendRefQueryDto { pub(crate) names: Option>, pub(crate) namespace: Option, + pub(crate) hosts: Option>, } impl ToInstance for BackendRefQueryDto { @@ -19,6 +20,7 @@ impl ToInstance for BackendRefQueryDto { Ok(BackendRefQueryInst { names: self.names.map(|n| n.into_iter().map(fuzzy_regex).collect::>>()).transpose()?, namespace: self.namespace.map(fuzzy_regex).transpose()?, + hosts: self.hosts.map(|n| n.into_iter().map(fuzzy_regex).collect::>>()).transpose()?, }) } } @@ -26,6 +28,7 @@ impl ToInstance for BackendRefQueryDto { pub struct BackendRefQueryInst { pub(crate) names: Option>, pub(crate) namespace: Option, + pub(crate) hosts: Option>, } impl Instance for BackendRefQueryInst {} diff --git a/admin/src/model/vo_converter/http_route_conv.rs b/admin/src/model/vo_converter/http_route_conv.rs index 1d36a8ba..cf9157e6 100644 --- a/admin/src/model/vo_converter/http_route_conv.rs +++ b/admin/src/model/vo_converter/http_route_conv.rs @@ -16,18 +16,19 @@ use tardis::futures_util::future::join_all; #[async_trait] impl VoConv for SgHttpRouteVo { async fn to_model(self, client_name: &str) -> TardisResult { - Ok(SgHttpRoute { + let result = SgHttpRoute { name: self.name, gateway_name: self.gateway_name, priority: self.priority, hostnames: self.hostnames, filters: SgFilterVoConv::ids_to_filter(client_name, self.filters).await?, - rules: if self.rules.is_empty() { + rules: if !self.rules.is_empty() { Some(SgHttpRouteRuleVo::to_vec_model(client_name, self.rules).await?) } else { None }, - }) + }; + Ok(result) } async fn from_model(model: SgHttpRoute) -> TardisResult { @@ -55,7 +56,7 @@ struct SgBackendRefVoConv; impl SgBackendRefVoConv { async fn ids_to_backends(client_name: &str, ids: Vec) -> TardisResult>> { - Ok(if ids.is_empty() { + Ok(if !ids.is_empty() { Some( join_all( BackendRefVoService::list( @@ -84,12 +85,13 @@ impl SgBackendRefVoConv { #[async_trait] impl VoConv for SgHttpRouteRuleVo { async fn to_model(self, client_name: &str) -> TardisResult { - Ok(SgHttpRouteRule { + let result = SgHttpRouteRule { matches: self.matches, filters: SgFilterVoConv::ids_to_filter(client_name, self.filters).await?, backends: SgBackendRefVoConv::ids_to_backends(client_name, self.backends).await?, timeout_ms: self.timeout_ms, - }) + }; + Ok(result) } async fn from_model(model: SgHttpRouteRule) -> TardisResult { diff --git a/admin/src/model/vo_converter/plugin_vo_conv.rs b/admin/src/model/vo_converter/plugin_vo_conv.rs index 45648c7b..f57d1d4a 100644 --- a/admin/src/model/vo_converter/plugin_vo_conv.rs +++ b/admin/src/model/vo_converter/plugin_vo_conv.rs @@ -12,6 +12,8 @@ pub struct SgFilterVoConv {} impl SgFilterVoConv { pub(crate) async fn ids_to_filter(client_name: &str, filters: Vec) -> TardisResult>> { Ok(if filters.is_empty() { + None + } else { Some( join_all( PluginVoService::list( @@ -31,8 +33,6 @@ impl SgFilterVoConv { .into_iter() .collect::>>()?, ) - } else { - None }) } diff --git a/admin/src/service/backend_ref_service.rs b/admin/src/service/backend_ref_service.rs index b64decf3..78065327 100644 --- a/admin/src/service/backend_ref_service.rs +++ b/admin/src/service/backend_ref_service.rs @@ -16,7 +16,7 @@ impl BackendRefVoService { .into_values() .filter(|b| if let Some(q_names) = &query.names { - q_names.iter().any(|q| q.is_match(&b.name_or_host)) + q_names.iter().any(|q| q.is_match(&b.id)) } else { true } && @@ -27,7 +27,9 @@ impl BackendRefVoService { else { false } } else { true - } + } && query.hosts.as_ref().map_or(true, |hosts| { + hosts.iter().any(|host| host.is_match(&b.name_or_host)) + }) ) .collect()) } diff --git a/admin/src/service/route_service.rs b/admin/src/service/route_service.rs index 90fa84b5..a182695c 100644 --- a/admin/src/service/route_service.rs +++ b/admin/src/service/route_service.rs @@ -13,6 +13,7 @@ use kernel_common::{ }; use kube::api::{DeleteParams, PostParams}; use kube::{Api, ResourceExt}; +use tardis::basic::error::TardisError; use tardis::basic::result::TardisResult; use tardis::TardisFuns; @@ -44,6 +45,7 @@ impl HttpRouteVoService { } pub(crate) async fn add(client_name: &str, mut add: SgHttpRouteVo) -> TardisResult { + check_param(&add)?; let is_kube = SpacegateManageService::client_is_kube(client_name).await?; if is_kube { let (namespace, raw_nmae) = parse_k8s_unique_or_default(&add.get_unique_name()); @@ -69,7 +71,9 @@ impl HttpRouteVoService { } Self::add_vo(client_name, add).await } + pub(crate) async fn update(client_name: &str, update: SgHttpRouteVo) -> TardisResult { + check_param(&update)?; let update_un = &update.get_unique_name(); let update_sg_httproute = update.clone().to_model(client_name).await?; @@ -128,3 +132,14 @@ impl HttpRouteVoService { )) } } + +#[inline] +fn check_param(param: &SgHttpRouteVo) -> TardisResult<()> { + if param.gateway_name.is_empty() { + return Err(TardisError::bad_request("[Admin] gateway_name is empty", "")); + } + if param.name.is_empty() { + return Err(TardisError::bad_request("[Admin] name is empty", "")); + } + Ok(()) +} diff --git a/kernel-common/src/converter/http_route_k8s_conv.rs b/kernel-common/src/converter/http_route_k8s_conv.rs index 71d44fe7..3a84ca8a 100644 --- a/kernel-common/src/converter/http_route_k8s_conv.rs +++ b/kernel-common/src/converter/http_route_k8s_conv.rs @@ -1,6 +1,6 @@ use crate::constants::{self, BANCKEND_KIND_EXTERNAL, BANCKEND_KIND_EXTERNAL_HTTP, BANCKEND_KIND_EXTERNAL_HTTPS}; use crate::converter::plugin_k8s_conv::SgSingeFilter; -use crate::helper::k8s_helper::{get_k8s_obj_unique, parse_k8s_obj_unique}; +use crate::helper::k8s_helper::{format_k8s_obj_unique, get_k8s_obj_unique, parse_k8s_obj_unique}; use crate::inner_model::gateway::SgProtocol; use crate::inner_model::http_route::{ SgBackendRef, SgHttpHeaderMatch, SgHttpHeaderMatchType, SgHttpPathMatch, SgHttpPathMatchType, SgHttpQueryMatch, SgHttpQueryMatchType, SgHttpRoute, SgHttpRouteMatch, @@ -132,10 +132,14 @@ impl SgHttpRoute { } else { constants::RAW_HTTP_ROUTE_KIND_SPACEROUTE }; - let priority=httproute.annotations().get(crate::constants::ANNOTATION_RESOURCE_PRIORITY).and_then(|a| a.parse::().ok()).unwrap_or(0); + let priority = httproute.annotations().get(crate::constants::ANNOTATION_RESOURCE_PRIORITY).and_then(|a| a.parse::().ok()).unwrap_or(0); + let gateway_refs = httproute.spec.inner.parent_refs.clone().unwrap_or_default(); Ok(SgHttpRoute { name: get_k8s_obj_unique(&httproute), - gateway_name: httproute.spec.inner.parent_refs.clone().unwrap_or_default().get(0).map(|x| x.name.clone()).unwrap_or_default(), + gateway_name: format_k8s_obj_unique( + gateway_refs.get(0).and_then(|x| x.namespace.clone()).as_ref(), + &gateway_refs.get(0).map(|x| x.name.clone()).unwrap_or_default(), + ), hostnames: httproute.spec.hostnames.clone(), filters: SgRouteFilter::from_crd_filters(client_name, kind, &httproute.metadata.name, &httproute.metadata.namespace).await?, rules: httproute.spec.rules.map(|r_vec| r_vec.into_iter().map(|r| SgHttpRouteRule::from_kube_httproute(r)).collect::>>()).transpose()?, diff --git a/kernel-common/src/inner_model/http_route.rs b/kernel-common/src/inner_model/http_route.rs index fb0dfdc5..70ca1699 100644 --- a/kernel-common/src/inner_model/http_route.rs +++ b/kernel-common/src/inner_model/http_route.rs @@ -18,6 +18,8 @@ pub struct SgHttpRoute { pub name: String, /// Associated gateway name. pub gateway_name: String, + /// Priority is used to sort HTTPRoutes based on priority. Routes with higher priority are tried first. + pub priority: i64, /// Hostnames defines a set of hostname that should match against the HTTP Host header to select a HTTPRoute to process the request. pub hostnames: Option>, /// Filters define the filters that are applied to requests that match this hostnames.