Skip to content

Commit

Permalink
finish curd
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai committed Nov 15, 2023
1 parent b175991 commit e3b33e5
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 35 deletions.
1 change: 1 addition & 0 deletions admin/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use tardis::basic::result::TardisResult;
use tardis::regex;
use tardis::regex::Regex;

//todo 使用这个get_k8s_client还是common里的?
#[cfg(feature = "k8s")]
pub async fn get_k8s_client() -> TardisResult<Client> {
Client::try_default().await.map_err(|error| TardisError::wrap(&format!("[SG.admin] Get kubernetes client error: {error:?}"), ""))
Expand Down
74 changes: 65 additions & 9 deletions admin/src/service/route_service.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use crate::helper::get_k8s_client;
use crate::model::query_dto::HttpRouteQueryInst;
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 kernel_common::helper::k8s_helper::{format_k8s_obj_unique, parse_k8s_unique_or_default};
use crate::service::plugin_service::PluginK8sService;
use k8s_gateway_api::Gateway;
use kernel_common::converter::plugin_k8s_conv::SgSingeFilter;
use kernel_common::helper::k8s_helper::{format_k8s_obj_unique, parse_k8s_obj_unique, parse_k8s_unique_or_default, WarpKubeResult};
use kernel_common::k8s_crd::http_spaceroute::HttpSpaceroute;
use kube::api::{DeleteParams, PostParams};
use kube::Api;
use std::collections::HashSet;
use tardis::basic::result::TardisResult;

pub struct HttpRouteVoService;
Expand Down Expand Up @@ -34,7 +42,7 @@ impl HttpRouteVoService {
)
}

pub(crate) async fn add(mut add: SgHttpRouteVo) -> TardisResult<()> {
pub(crate) async fn add(mut add: SgHttpRouteVo) -> TardisResult<SgHttpRouteVo> {
#[cfg(feature = "k8s")]
{
let (namespace, raw_nmae) = parse_k8s_unique_or_default(&add.get_unique_name());
Expand All @@ -43,18 +51,66 @@ impl HttpRouteVoService {
let add_model = add.clone().to_model().await?;
#[cfg(feature = "k8s")]
{
add_model
let (namespace, _) = parse_k8s_unique_or_default(&add.get_unique_name());
let (httproute, sgfilters) = add_model.to_kube_httproute();
let http_route_api: Api<HttpSpaceroute> = Api::namespaced(get_k8s_client().await?, &namespace);

let _ = http_route_api.create(&PostParams::default(), &httproute).await.warp_result_by_method("Add HttpSpaceroute")?;

PluginK8sService::add_sgfilter_vec(&sgfilters.iter().collect::<Vec<_>>()).await?
}
Self::add_vo(add).await?;
Ok(())
Ok(Self::add_vo(add).await?)
}
pub(crate) async fn update(update: SgHttpRouteVo) -> TardisResult<()> {
Self::update_vo(update).await?;
Ok(())
pub(crate) async fn update(update: SgHttpRouteVo) -> TardisResult<SgHttpRouteVo> {
let update_un = &update.get_unique_name();

let update_sg_httproute = update.clone().to_model().await?;
let old_sg_httproute = Self::get_by_id(&update.name).await?.to_model().await?;
#[cfg(feature = "k8s")]
{
let (namespace, name) = parse_k8s_obj_unique(update_un);
let http_route_api: Api<HttpSpaceroute> = Api::namespaced(get_k8s_client().await?, &namespace);
let (update_httproute, update_filter) = update_sg_httproute.to_kube_httproute();
http_route_api.replace(&name, &PostParams::default(), &update_httproute).await.warp_result_by_method("Replace HttpSpaceroute")?;

Self::update_httproute_filter(old_sg_httproute.to_kube_httproute().1, update_filter).await?;
}
Ok(Self::update_vo(update).await?)
}

pub(crate) async fn delete(id: &str) -> TardisResult<()> {
Self::delete_vo(&id).await?;
let (namespace, name) = parse_k8s_obj_unique(id);
#[cfg(feature = "k8s")]
{
let http_route_api: Api<HttpSpaceroute> = Api::namespaced(get_k8s_client().await?, &namespace);

http_route_api.delete(&name, &DeleteParams::default()).await.warp_result_by_method("Delete HttpSpaceroute")?;

let old_sg_httproute = Self::get_by_id(&id).await?.to_model().await?;
let (_, f_v) = old_sg_httproute.to_kube_httproute();
PluginK8sService::delete_sgfilter_vec(&f_v.iter().collect::<Vec<_>>()).await?;
}
Self::delete_vo(id).await?;
Ok(())
}

//todo 和gateway_service 里的那个合并
#[cfg(feature = "k8s")]
async fn update_httproute_filter(old: Vec<SgSingeFilter>, update: Vec<SgSingeFilter>) -> TardisResult<()> {
if old.is_empty() && update.is_empty() {
return Ok(());
}

let old_set: HashSet<_> = old.into_iter().collect();
let update_set: HashSet<_> = update.into_iter().collect();

let update_vec: Vec<_> = old_set.intersection(&update_set).collect();
PluginK8sService::update_sgfilter_vec(&update_vec).await?;
let add_vec: Vec<_> = update_set.difference(&old_set).collect();
PluginK8sService::add_sgfilter_vec(&add_vec).await?;
let delete_vec: Vec<_> = old_set.difference(&update_set).collect();
PluginK8sService::delete_sgfilter_vec(&delete_vec).await?;

Ok(())
}
}
4 changes: 4 additions & 0 deletions kernel-common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ pub mod k8s_constants;
pub const RAW_HTTP_ROUTE_KIND: &str = "raw.http.route.kind";
pub const RAW_HTTP_ROUTE_KIND_DEFAULT: &str = "HTTPRoute";
pub const RAW_HTTP_ROUTE_KIND_SPACEROUTE: &str = "HTTPSpaceroute";

pub const BANCKEND_KIND_EXTERNAL: &str = "External";
pub const BANCKEND_KIND_EXTERNAL_HTTP: &str = "ExternalHttp";
pub const BANCKEND_KIND_EXTERNAL_HTTPS: &str = "ExternalHttps";
34 changes: 24 additions & 10 deletions kernel-common/src/converter/http_route_k8s_conv.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::constants::{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::inner_model::gateway::SgProtocol;
use crate::inner_model::http_route::{
SgBackendRef, SgHttpHeaderMatch, SgHttpHeaderMatchType, SgHttpPathMatch, SgHttpPathMatchType, SgHttpQueryMatch, SgHttpQueryMatchType, SgHttpRoute, SgHttpRouteMatch,
SgHttpRouteRule,
Expand Down Expand Up @@ -29,7 +31,7 @@ impl SgHttpRoute {
.map(|filters| {
filters
.into_iter()
.map(|f| {
.filter_map(|f| {
f.to_singe_filter(K8sSgFilterSpecTargetRef {
kind: "HTTPSpaceroute".to_string(),
name: self.name.clone(),
Expand All @@ -52,7 +54,7 @@ impl SgHttpRoute {
.map(|b_f_vec| {
b_f_vec
.iter()
.map(|b_f| {
.filter_map(|b_f| {
b_f.clone().to_singe_filter(K8sSgFilterSpecTargetRef {
kind: "HTTPSpaceroute".to_string(),
name: self.name.clone(),
Expand Down Expand Up @@ -83,7 +85,7 @@ impl SgHttpRoute {
.map(|filters| {
filters
.into_iter()
.map(|f| {
.filter_map(|f| {
f.to_singe_filter(K8sSgFilterSpecTargetRef {
kind: "HTTPSpaceroute".to_string(),
name: self.name.clone(),
Expand Down Expand Up @@ -135,7 +137,8 @@ impl SgHttpRoute {
}

impl SgHttpRouteRule {
/// `SgHttpRouteRule` to `HttpRouteRule`, excluding SgFilter.
/// # to_kube_httproute
/// `SgHttpRouteRule` to `HttpRouteRule`, include `HttpRouteFilter` and excluding `SgFilter`.
pub(crate) fn to_kube_httproute(self) -> HttpRouteRule {
HttpRouteRule {
matches: self.matches.map(|m_vec| m_vec.into_iter().map(|m| m.to_kube_httproute()).flatten().collect::<Vec<_>>()),
Expand Down Expand Up @@ -210,21 +213,32 @@ impl SgHttpQueryMatch {
}

impl SgBackendRef {
//todo excluding SgFilter.
pub(crate) fn to_kube_httproute(self) -> HttpBackendRef {
let kind = if self.namespace.is_none() {
match self.protocol {
Some(SgProtocol::Http) => Some(BANCKEND_KIND_EXTERNAL_HTTP.to_string()),
Some(SgProtocol::Https) => Some(BANCKEND_KIND_EXTERNAL_HTTPS.to_string()),
Some(SgProtocol::Ws) => Some(BANCKEND_KIND_EXTERNAL.to_string()),
Some(SgProtocol::Wss) => Some(BANCKEND_KIND_EXTERNAL.to_string()),
_ => None,
}
} else {
None
};

HttpBackendRef {
backend_ref: Some(BackendRef {
weight: None,
timeout_ms: None,
weight: self.weight,
timeout_ms: self.timeout_ms,
inner: BackendObjectReference {
group: None,
kind: None,
kind,
name: self.name_or_host,
namespace: self.namespace,
port: None,
port: Some(self.port),
},
}),
filters: None,
filters: self.filters.map(|f_vec| f_vec.into_iter().filter_map(|f| f.to_http_route_filter()).collect()),
}
}
}
33 changes: 22 additions & 11 deletions kernel-common/src/converter/plugin_k8s_conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,31 @@ use std::hash::{Hash, Hasher};
use tardis::TardisFuns;

impl SgRouteFilter {
pub fn to_singe_filter(self, target: K8sSgFilterSpecTargetRef) -> SgSingeFilter {
SgSingeFilter {
name: self.name,
namespace: target.namespace.clone().unwrap_or(DEFAULT_NAMESPACE.to_string()),
filter: K8sSgFilterSpecFilter {
code: self.code,
name: None,
enable: true,
config: self.spec,
},
target_ref: target,
/// # to_singe_filter
/// `to_single_filter` method and [SgRouteFilter::to_http_route_filter] method both convert from
/// `SgRouteFilter`to the k8s model. The difference lies in that `to_single_filter` only includes
/// the k8s object of `SGFilter`, whereas `to_http_route_filter` is used to convert to `HttpRouteFilter`,
/// a filter defined in the Gateway API.
pub fn to_singe_filter(self, target: K8sSgFilterSpecTargetRef) -> Option<SgSingeFilter> {
if self.code == SG_FILTER_HEADER_MODIFIER_CODE || self.code == SG_FILTER_REDIRECT_CODE || self.code == SG_FILTER_REWRITE_CODE {
None
} else {
Some(SgSingeFilter {
name: self.name,
namespace: target.namespace.clone().unwrap_or(DEFAULT_NAMESPACE.to_string()),
filter: K8sSgFilterSpecFilter {
code: self.code,
name: None,
enable: true,
config: self.spec,
},
target_ref: target,
})
}
}

/// # to_http_route_filter
/// ref [SgRouteFilter::to_singe_filter]
pub fn to_http_route_filter(self) -> Option<HttpRouteFilter> {
if &self.code == SG_FILTER_HEADER_MODIFIER_CODE {
if let Ok(header) = TardisFuns::json.json_to_obj::<SgFilterHeaderModifier>(self.spec) {
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/config/config_by_k8s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ use tardis::{

use crate::{do_startup, functions::http_route, shutdown};

use crate::constants::{BANCKEND_KIND_EXTERNAL, BANCKEND_KIND_EXTERNAL_HTTP, BANCKEND_KIND_EXTERNAL_HTTPS};
use crate::helpers::k8s_helper;
use kernel_common::constants::k8s_constants::{DEFAULT_NAMESPACE, GATEWAY_CLASS_NAME};
use kernel_common::constants::{BANCKEND_KIND_EXTERNAL, BANCKEND_KIND_EXTERNAL_HTTP, BANCKEND_KIND_EXTERNAL_HTTPS};
use kernel_common::gatewayapi_support_filter::SgFilterHeaderModifierKind;
use kernel_common::helper;
use kernel_common::helper::k8s_helper::{get_k8s_obj_unique, WarpKubeResult};
Expand Down
4 changes: 0 additions & 4 deletions kernel/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
pub const DOMAIN_CODE: &str = "spacegate_kernel";

pub const ANNOTATION_RESOURCE_PRIORITY: &str = "priority";

pub const BANCKEND_KIND_EXTERNAL: &str = "External";
pub const BANCKEND_KIND_EXTERNAL_HTTP: &str = "ExternalHttp";
pub const BANCKEND_KIND_EXTERNAL_HTTPS: &str = "ExternalHttps";

0 comments on commit e3b33e5

Please sign in to comment.