Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai committed Dec 7, 2023
1 parent 9ff8c0d commit 0c5dca7
Show file tree
Hide file tree
Showing 8 changed files with 462 additions and 29 deletions.
13 changes: 9 additions & 4 deletions admin/src/api/dashboard_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use tardis::web::poem::session::Session;
use tardis::web::poem_openapi;
use tardis::web::web_resp::{TardisApiResult, TardisResp};

use crate::model::query_dto::{GatewayQueryInst, HttpRouteQueryInst, PluginQueryInst};
use crate::model::query_dto::{BackendRefQueryInst, GatewayQueryInst, HttpRouteQueryInst, PluginQueryInst};
use crate::service::backend_ref_service::BackendRefVoService;
use crate::service::gateway_service::GatewayVoService;
use crate::{
model::query_dto::{SgTlsQueryInst, SpacegateInstQueryInst},
Expand All @@ -14,12 +15,14 @@ use crate::{
pub struct DashboardApi;

/// Dashboard API
#[poem_openapi::OpenApi(prefix_path = "/")]
#[poem_openapi::OpenApi(prefix_path = "/dashboard")]
impl DashboardApi {
#[oai(path = "/", method = "get")]
/// Get Dashboard Metrics
#[oai(path = "/statistics", method = "get")]
async fn statistics(&self, session: &Session) -> TardisApiResult<Statistics> {
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,
gateway_count: GatewayVoService::list(
client_name,
GatewayQueryInst {
Expand Down Expand Up @@ -57,13 +60,15 @@ impl DashboardApi {
.await?
.len() as i64,
tls_count: TlsVoService::list(client_name, SgTlsQueryInst { names: None }).await?.len() as i64,
instance_count: SpacegateManageService::list(SpacegateInstQueryInst { names: None }).await?.len() as i64,
// add default instance
instance_count: SpacegateManageService::list(SpacegateInstQueryInst { names: None }).await?.len() as i64 + 1,
})
}
}

#[derive(Default, Debug, Serialize, Deserialize, Clone, poem_openapi::Object)]
struct Statistics {
pub backend_count: i64,
pub gateway_count: i64,
pub route_count: i64,
pub plugin_count: i64,
Expand Down
111 changes: 109 additions & 2 deletions admin/src/initializer.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,129 @@
use crate::api::{auth_api, backend_api, gateway_api, plugin_api, route_api, spacegate_manage_api, tls_api, BasicAuth, CookieMW};
use crate::api::{auth_api, backend_api, dashboard_api, gateway_api, plugin_api, route_api, spacegate_manage_api, tls_api, BasicAuth, CookieMW};
use crate::client::init_client;

use crate::constants::DOMAIN_CODE;
use crate::model::vo::gateway_vo::SgGatewayVo;
use crate::model::vo::http_route_vo::SgHttpRouteVo;
use crate::model::vo::Vo;
use crate::model::vo_converter::VoConv;
use crate::service::base_service::VoBaseService;
use crate::service::gateway_service::GatewayVoService;
use k8s_gateway_api::{Gateway, HttpRoute};
use kernel_common::client::{cache_client, k8s_client};
use kernel_common::constants::k8s_constants::GATEWAY_CLASS_NAME;
use kernel_common::helper::k8s_helper::WarpKubeResult;
use kernel_common::inner_model::gateway::SgGateway;
use kernel_common::inner_model::http_route::SgHttpRoute;
use kernel_common::k8s_crd::http_spaceroute::{self, HttpSpaceroute};
use kernel_common::k8s_crd::sg_filter::SgFilter;
use kube::api::ListParams;
use kube::Api;
use tardis::basic::error::TardisError;
use tardis::basic::result::TardisResult;

use tardis::futures_util::future::join_all;
use tardis::web::web_server::{TardisWebServer, WebServerModule};
use tardis::TardisFuns;

use crate::{
model::query_dto::{SgTlsQueryInst, SpacegateInstQueryInst},
service::{plugin_service::PluginVoService, route_service::HttpRouteVoService, secret_service::TlsVoService, spacegate_manage_service::SpacegateManageService},
};

pub(crate) async fn init(web_server: &TardisWebServer) -> TardisResult<()> {
let funs = TardisFuns::inst(DOMAIN_CODE.to_string(), None);
init_client(&funs).await?;
// todo 根据现有的k8s资源初始化成VO
init_spacegate_to_config().await?;
init_api(web_server).await
}

/// Initialized to VO based on existing instance
async fn init_spacegate_to_config() -> TardisResult<()> {
for inst_vo in SpacegateManageService::list(SpacegateInstQueryInst { names: None }).await? {
let client_name_string = inst_vo.get_unique_name();
let client_name = client_name_string.as_str();
let (gateway_models, http_spaceroute_models) = match inst_vo.type_ {
crate::model::vo::spacegate_inst_vo::InstConfigType::K8sClusterConfig => {
let (gateway_api, http_spaceroute_api, http_route_api): (Api<Gateway>, Api<HttpSpaceroute>, Api<HttpRoute>) = (
Api::all((*k8s_client::get(client_name).await?).clone()),
Api::all((*k8s_client::get(client_name).await?).clone()),
Api::all((*k8s_client::get(client_name).await?).clone()),
);
let gateway_objs = gateway_api
.list(&ListParams::default())
.await
.warp_result()?
.into_iter()
.filter(|gateway_obj| gateway_obj.spec.gateway_class_name == GATEWAY_CLASS_NAME)
.collect::<Vec<Gateway>>();
let gateway_models =
join_all(gateway_objs.into_iter().map(|gateway_obj| async move { return SgGateway::from_kube_gateway(client_name, gateway_obj).await }).collect::<Vec<_>>())
.await
.into_iter()
.collect::<TardisResult<Vec<_>>>()?;
let gateway_uniques = gateway_models.iter().map(|gateway_config| gateway_config.name.clone()).collect::<Vec<String>>();

let http_route_objs: Vec<HttpSpaceroute> = http_spaceroute::get_http_spaceroute_by_api(&gateway_uniques, (&http_spaceroute_api, &http_route_api)).await?;

let http_route_models =
join_all(http_route_objs.into_iter().map(|http_route_obj| return SgHttpRoute::from_kube_httpspaceroute(client_name, http_route_obj)).collect::<Vec<_>>())
.await
.into_iter()
.collect::<TardisResult<Vec<_>>>()?;
(gateway_models, http_route_models)
}
crate::model::vo::spacegate_inst_vo::InstConfigType::RedisConfig => {
let redis_client = cache_client::get(&client_name).await?;

let gateway_configs = redis_client.hgetall(cache_client::CONF_GATEWAY_KEY).await?;
if gateway_configs.is_empty() {
return Err(TardisError::not_found(
&format!("[Admin.Init] Gateway Config not found in {}", cache_client::CONF_GATEWAY_KEY),
"",
));
}
let gateway_models = gateway_configs
.into_values()
.map(|v| {
tardis::TardisFuns::json.str_to_obj::<SgGateway>(&v).map_err(|e| TardisError::format_error(&format!("[SG.Config] Gateway Config parse error {}", e), ""))
})
.collect::<TardisResult<Vec<SgGateway>>>()?;

let http_route_models = Vec::new();
for gateway_model in &gateway_models {
let http_route_configs = redis_client.lrangeall(&format!("{}{}", cache_client::CONF_HTTP_ROUTE_KEY, gateway_model.name)).await?;
let http_route_configs = http_route_configs
.into_iter()
.map(|v| {
tardis::TardisFuns::json
.str_to_obj::<SgHttpRoute>(&v)
.map_err(|e| TardisError::format_error(&format!("[SG.Config] Http Route Config parse error {}", e), ""))
})
.collect::<TardisResult<Vec<SgHttpRoute>>>()?;
}
(gateway_models, http_route_models)
}
};

//Add gatewayVo
for gateway_model in gateway_models {
let add_model = SgGatewayVo::from_model(gateway_model).await?;
let _ = GatewayVoService::add(client_name, add_model).await;
}

//Add httprouteVO
for http_spaceroute_model in http_spaceroute_models {
let add_model = SgHttpRouteVo::from_model(http_spaceroute_model).await?;
let _ = HttpRouteVoService::add_vo(client_name, add_model).await;
}
}
Ok(())
}

async fn init_api(web_server: &TardisWebServer) -> TardisResult<()> {
let module = WebServerModule::from((
backend_api::BackendApi,
dashboard_api::DashboardApi,
gateway_api::GatewayApi,
plugin_api::PluginApi,
route_api::HttprouteApi,
Expand Down
6 changes: 4 additions & 2 deletions admin/src/model/vo/spacegate_inst_vo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ impl Vo for InstConfigVo {

fn get_unique_name(&self) -> String {
match &self.type_ {
InstConfigType::K8sClusterConfig => self.k8s_cluster_config.as_ref().expect("").name.clone(),
InstConfigType::RedisConfig => self.redis_config.as_ref().expect("").name.clone(),
InstConfigType::K8sClusterConfig => {
self.k8s_cluster_config.as_ref().expect(&format!("[admin] have inst config {self:?} type is k8s cluster config , but not found ")).name.clone()
}
InstConfigType::RedisConfig => self.redis_config.as_ref().expect(&format!("[admin] have inst config {self:?} type is redis config , but not found ")).name.clone(),
}
}
}
Expand Down
13 changes: 5 additions & 8 deletions kernel-common/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,15 @@ pub mod cache_client {
}

pub async fn remove(name: &str) -> TardisResult<()> {
{
let mut write = cache_clients().write().await;
write.remove(name);
}
let mut write = cache_clients().write().await;
write.remove(name);

Ok(())
}

pub async fn get(name: &str) -> TardisResult<Arc<TardisCacheClient>> {
{
let read = cache_clients().read().await;
read.get(name).cloned().ok_or_else(|| TardisError::bad_request(&format!("[SG.common] Get cache client [{name}] failed"), ""))
}
let read = cache_clients().read().await;
read.get(name).cloned().ok_or_else(|| TardisError::bad_request(&format!("[SG.common] Get cache client [{name}] failed"), ""))
}

/// # Add orUpdate object
Expand Down
4 changes: 2 additions & 2 deletions kernel-common/src/converter/gateway_k8s_conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::constants::k8s_constants::GATEWAY_CLASS_NAME;
use crate::converter::plugin_k8s_conv::SgSingeFilter;
use crate::helper::k8s_helper::{get_k8s_obj_unique, parse_k8s_obj_unique};
use crate::inner_model::gateway::{SgGateway, SgListener, SgParameters, SgProtocol, SgTls, SgTlsConfig, SgTlsMode};
use crate::inner_model::plugin_filter::SgRouteFilter;
use crate::k8s_crd::sg_filter::{K8sSgFilterSpecFilter, K8sSgFilterSpecTargetRef};
use k8s_gateway_api::{Gateway, GatewaySpec, GatewayTlsConfig, Listener, SecretObjectReference, TlsModeType};
use k8s_openapi::api::core::v1::Secret;
Expand Down Expand Up @@ -87,8 +88,7 @@ impl SgGateway {
}

pub async fn from_kube_gateway(client_name: &str, gateway: Gateway) -> TardisResult<SgGateway> {
//todo filters
let filters = None;
let filters = SgRouteFilter::from_crd_filters(client_name, "gateway", &gateway.metadata.name, &gateway.metadata.namespace).await?;
let result = SgGateway {
name: get_k8s_obj_unique(&gateway),
parameters: SgParameters::from_kube_gateway(&gateway),
Expand Down
Loading

0 comments on commit 0c5dca7

Please sign in to comment.