Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
RWDai committed Nov 15, 2023
1 parent bee1a1b commit 4189a1b
Show file tree
Hide file tree
Showing 14 changed files with 119 additions and 98 deletions.
2 changes: 1 addition & 1 deletion admin/src/service/gateway_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::model::vo::Vo;
#[cfg(feature = "k8s")]
use k8s_gateway_api::Gateway;
#[cfg(feature = "k8s")]
use kernel_common::constants::DEFAULT_NAMESPACE;
use kernel_common::constants::k8s_constants::DEFAULT_NAMESPACE;
#[cfg(feature = "k8s")]
use kube::api::{DeleteParams, PostParams};
use std::collections::HashSet;
Expand Down
2 changes: 1 addition & 1 deletion admin/src/service/plugin_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::model::vo::plugin_vo::SgFilterVo;
use crate::model::vo::Vo;
use crate::service::base_service::VoBaseService;
#[cfg(feature = "k8s")]
use kernel_common::constants::DEFAULT_NAMESPACE;
use kernel_common::constants::k8s_constants::DEFAULT_NAMESPACE;
use kernel_common::converter::plugin_k8s_conv::SgSingeFilter;
use kernel_common::helper::k8s_helper::{format_k8s_obj_unique, parse_k8s_unique_or_default, WarpKubeResult};
use kernel_common::k8s_crd::sg_filter::K8sSgFilterSpecFilter;
Expand Down
13 changes: 1 addition & 12 deletions kernel-common/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
#[cfg(feature = "k8s")]
pub const GATEWAY_ANNOTATION_REDIS_URL: &str = "redis_url";
#[cfg(feature = "k8s")]
pub const GATEWAY_ANNOTATION_LOG_LEVEL: &str = "log_level";
#[cfg(feature = "k8s")]
pub const GATEWAY_ANNOTATION_LANGUAGE: &str = "lang";
#[cfg(feature = "k8s")]
pub const GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION: &str = "ignore_tls_verification";

#[cfg(feature = "k8s")]
pub const GATEWAY_CLASS_NAME: &str = "spacegate";
#[cfg(feature = "k8s")]
pub const DEFAULT_NAMESPACE: &str = "default";
pub mod k8s_constants;

pub const RAW_HTTP_ROUTE_KIND: &str = "raw.http.route.kind";
pub const RAW_HTTP_ROUTE_KIND_DEFAULT: &str = "HTTPRoute";
Expand Down
9 changes: 9 additions & 0 deletions kernel-common/src/constants/k8s_constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub const GATEWAY_CLASS_NAME: &str = "spacegate";
pub const GATEWAY_ANNOTATION_REDIS_URL: &str = "redis_url";
pub const GATEWAY_ANNOTATION_LOG_LEVEL: &str = "log_level";
pub const GATEWAY_ANNOTATION_LANGUAGE: &str = "lang";
pub const GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION: &str = "ignore_tls_verification";
pub const DEFAULT_NAMESPACE: &str = "default";

/// gateway api support filter code
pub const GATEWAYAPI_SUPPORT_FILTER_CODE: [&str; 3] = ["header_modifier", "redirect", "rewrite"];
19 changes: 10 additions & 9 deletions kernel-common/src/converter/gateway_k8s_conv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::constants::{DEFAULT_NAMESPACE, GATEWAY_CLASS_NAME};
use crate::constants::k8s_constants::DEFAULT_NAMESPACE;
use crate::constants::k8s_constants::GATEWAY_CLASS_NAME;
use crate::converter::plugin_k8s_conv::SgSingeFilter;
use crate::helper::k8s_helper::{get_k8s_client, get_k8s_obj_unique, parse_k8s_obj_unique};
use crate::inner_model::gateway::{SgGateway, SgListener, SgParameters, SgProtocol, SgTls, SgTlsConfig, SgTlsMode};
Expand Down Expand Up @@ -145,17 +146,17 @@ impl SgParameters {
pub(crate) fn to_kube_gateway(self) -> BTreeMap<String, String> {
let mut ann = BTreeMap::new();
if let Some(redis_url) = self.redis_url {
ann.insert(crate::constants::GATEWAY_ANNOTATION_REDIS_URL.to_string(), redis_url);
ann.insert(crate::constants::k8s_constants::GATEWAY_ANNOTATION_REDIS_URL.to_string(), redis_url);
}
if let Some(log_level) = self.log_level {
ann.insert(crate::constants::GATEWAY_ANNOTATION_LOG_LEVEL.to_string(), log_level);
ann.insert(crate::constants::k8s_constants::GATEWAY_ANNOTATION_LOG_LEVEL.to_string(), log_level);
}
if let Some(lang) = self.lang {
ann.insert(crate::constants::GATEWAY_ANNOTATION_LANGUAGE.to_string(), lang);
ann.insert(crate::constants::k8s_constants::GATEWAY_ANNOTATION_LANGUAGE.to_string(), lang);
}
if let Some(ignore_tls_verification) = self.ignore_tls_verification {
ann.insert(
crate::constants::GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION.to_string(),
crate::constants::k8s_constants::GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION.to_string(),
ignore_tls_verification.to_string(),
);
}
Expand All @@ -166,10 +167,10 @@ impl SgParameters {
let gateway_annotations = gateway.metadata.annotations.clone();
if let Some(gateway_annotations) = gateway_annotations {
SgParameters {
redis_url: gateway_annotations.get(crate::constants::GATEWAY_ANNOTATION_REDIS_URL).map(|v| v.to_string()),
log_level: gateway_annotations.get(crate::constants::GATEWAY_ANNOTATION_LOG_LEVEL).map(|v| v.to_string()),
lang: gateway_annotations.get(crate::constants::GATEWAY_ANNOTATION_LANGUAGE).map(|v| v.to_string()),
ignore_tls_verification: gateway_annotations.get(crate::constants::GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION).and_then(|v| v.parse::<bool>().ok()),
redis_url: gateway_annotations.get(crate::constants::k8s_constants::GATEWAY_ANNOTATION_REDIS_URL).map(|v| v.to_string()),
log_level: gateway_annotations.get(crate::constants::k8s_constants::GATEWAY_ANNOTATION_LOG_LEVEL).map(|v| v.to_string()),
lang: gateway_annotations.get(crate::constants::k8s_constants::GATEWAY_ANNOTATION_LANGUAGE).map(|v| v.to_string()),
ignore_tls_verification: gateway_annotations.get(crate::constants::k8s_constants::GATEWAY_ANNOTATION_IGNORE_TLS_VERIFICATION).and_then(|v| v.parse::<bool>().ok()),
}
} else {
SgParameters {
Expand Down
36 changes: 27 additions & 9 deletions kernel-common/src/converter/http_route_k8s_conv.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
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;
use crate::inner_model::http_route::{
SgHttpHeaderMatch, SgHttpHeaderMatchType, SgHttpPathMatch, SgHttpPathMatchType, SgHttpQueryMatch, SgHttpQueryMatchType, SgHttpRoute, SgHttpRouteMatch, SgHttpRouteRule,
SgBackendRef, SgHttpHeaderMatch, SgHttpHeaderMatchType, SgHttpPathMatch, SgHttpPathMatchType, SgHttpQueryMatch, SgHttpQueryMatchType, SgHttpRoute, SgHttpRouteMatch,
SgHttpRouteRule,
};
use crate::k8s_crd::http_spaceroute::{HttpRouteRule, HttpSpaceroute, HttpSpacerouteSpec};
use crate::k8s_crd::http_spaceroute::{BackendRef, HttpBackendRef, HttpRouteRule, HttpSpaceroute, HttpSpacerouteSpec};
use crate::k8s_crd::sg_filter::{K8sSgFilterSpecFilter, K8sSgFilterSpecTargetRef};
use k8s_gateway_api::{CommonRouteSpec, Gateway, HttpHeaderMatch, HttpPathMatch, HttpQueryParamMatch, HttpRouteMatch, ParentReference};
use k8s_gateway_api::{BackendObjectReference, CommonRouteSpec, Gateway, HttpHeaderMatch, HttpPathMatch, HttpQueryParamMatch, HttpRouteMatch, ParentReference};
use k8s_openapi::apimachinery::pkg::apis::meta::v1::ObjectMeta;
// use schemars::schema::SingleOrVec::Vec;
use tardis::basic::result::TardisResult;
use tardis::web::poem::EndpointExt;

impl SgHttpRoute {
pub fn to_kube_httproute(self) -> (HttpSpaceroute, Vec<SgSingeFilter>) {
Expand Down Expand Up @@ -135,12 +133,12 @@ impl SgHttpRoute {
}

impl SgHttpRouteRule {
//todo 不包括filters
/// `SgHttpRouteRule` to `HttpRouteRule`, 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<_>>()),
filters: None,
backend_refs: self.backends,
filters: self.filters.map(|f_vec| f_vec.into_iter().filter_map(|f| f.to_http_route_filter()).collect::<Vec<_>>()),
backend_refs: self.backends.map(|b_vec| b_vec.into_iter().map(|b| b.to_kube_httproute()).collect::<Vec<_>>()),
timeout_ms: self.timeout_ms,
}
}
Expand Down Expand Up @@ -208,3 +206,23 @@ impl SgHttpQueryMatch {
}
}
}

impl SgBackendRef {
//todo excluding SgFilter.
pub(crate) fn to_kube_httproute(&self) -> HttpBackendRef {
HttpBackendRef {
backend_ref: Some(BackendRef {
weight: None,
timeout_ms: None,
inner: BackendObjectReference {
group: None,
kind: None,
name: self.name_or_host,
namespace: self.namespace,
port: None,
},
}),
filters: None,
}
}
}
32 changes: 31 additions & 1 deletion kernel-common/src/converter/plugin_k8s_conv.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::constants::DEFAULT_NAMESPACE;
use crate::constants::k8s_constants::DEFAULT_NAMESPACE;
use crate::gatewayapi_support_filter::{SgFilterHeaderModifier, SgFilterHeaderModifierKind};
use crate::inner_model::plugin_filter::SgRouteFilter;
use crate::k8s_crd::sg_filter::{K8sSgFilterSpecFilter, K8sSgFilterSpecTargetRef};
use k8s_gateway_api::{HttpHeader, HttpRequestHeaderFilter, HttpRouteFilter};
use std::hash::{Hash, Hasher};
use tardis::TardisFuns;

impl SgRouteFilter {
pub fn to_singe_filter(self, target: K8sSgFilterSpecTargetRef) -> SgSingeFilter {
Expand All @@ -17,6 +20,33 @@ impl SgRouteFilter {
target_ref: target,
}
}

pub fn to_http_route_filter(self) -> Option<HttpRouteFilter> {
if &self.code == "header_modifier" {
if let Ok(header) = TardisFuns::json.json_to_obj::<SgFilterHeaderModifier>(self.spec) {
let header_filter = HttpRequestHeaderFilter {
set: header.sets.map(|header_map| header_map.into_iter().map(|(k, v)| HttpHeader { name: k, value: v }).collect()),
add: None,
remove: header.remove,
};
match header.kind {
SgFilterHeaderModifierKind::Request => Some(HttpRouteFilter::RequestHeaderModifier {
request_header_modifier: header_filter,
}),
SgFilterHeaderModifierKind::Response => Some(HttpRouteFilter::ResponseHeaderModifier {
response_header_modifier: header_filter,
}),
}
} else {
None
}
//todo
// } else if &self.code == "redirect" {
// if let Ok(header) = TardisFuns::json.json_to_obj::<SgFilterHeaderModifier>(self.spec) {}
} else {
None
}
}
}

#[cfg(feature = "k8s")]
Expand Down
16 changes: 16 additions & 0 deletions kernel-common/src/gatewayapi_support_filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct SgFilterHeaderModifier {
pub kind: SgFilterHeaderModifierKind,
pub sets: Option<HashMap<String, String>>,
pub remove: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
pub enum SgFilterHeaderModifierKind {
#[default]
Request,
Response,
}
2 changes: 1 addition & 1 deletion kernel-common/src/helper/k8s_helper.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::DEFAULT_NAMESPACE;
use crate::constants::k8s_constants::DEFAULT_NAMESPACE;
use kube::{Client, ResourceExt};
use tardis::basic::error::TardisError;
use tardis::basic::result::TardisResult;
Expand Down
33 changes: 1 addition & 32 deletions kernel-common/src/k8s_crd/http_spaceroute.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::constants;
use k8s_gateway_api::{CommonRouteSpec, Group, Hostname, HttpRoute, HttpRouteFilter, HttpRouteMatch, Kind, Namespace, ObjectName, PortNumber, RouteStatus};
use k8s_gateway_api::{BackendObjectReference, CommonRouteSpec, Group, Hostname, HttpRoute, HttpRouteFilter, HttpRouteMatch, Kind, Namespace, ObjectName, PortNumber, RouteStatus};
use k8s_openapi::apimachinery::pkg::apis::meta::v1::ObjectMeta;
use std::collections::BTreeMap;

Expand Down Expand Up @@ -229,37 +229,6 @@ pub struct BackendRef {
pub inner: BackendObjectReference,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
pub struct BackendObjectReference {
/// Group is the group of the referent. For example, "networking.k8s.io".
/// When unspecified (empty string), core API group is inferred.
pub group: Option<Group>,

/// Kind is kind of the referent. For example "HTTPRoute" or "Service".
/// Defaults to "Service" when not specified.
pub kind: Option<Kind>,

/// Name is the name of the referent.
pub name: ObjectName,

/// Namespace is the namespace of the backend. When unspecified, the local
/// namespace is inferred.
///
/// Note that when a namespace is specified, a ReferencePolicy object
/// is required in the referent namespace to allow that namespace's
/// owner to accept the reference. See the ReferencePolicy documentation
/// for details.
///
/// Support: Core
pub namespace: Option<Namespace>,

/// Port specifies the destination port number to use for this resource.
/// Port is required when the referent is a Kubernetes Service. For other
/// resources, destination port might be derived from the referent resource
/// or this field.
pub port: Option<PortNumber>,
}

impl From<HttpRoute> for HttpSpaceroute {
fn from(http_route_obj: HttpRoute) -> Self {
HttpSpaceroute {
Expand Down
2 changes: 1 addition & 1 deletion kernel-common/src/k8s_crd/sg_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use k8s_openapi::schemars::JsonSchema;
use kube::CustomResource;

use crate::constants::DEFAULT_NAMESPACE;
use crate::constants::k8s_constants::DEFAULT_NAMESPACE;
use serde_json::value::Value;

#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
Expand Down
2 changes: 2 additions & 0 deletions kernel-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub mod constants;
#[cfg(feature = "k8s")]
pub mod converter;
#[cfg(feature = "k8s")]
pub mod gatewayapi_support_filter;
pub mod helper;
pub mod inner_model;
#[cfg(feature = "k8s")]
Expand Down
17 changes: 8 additions & 9 deletions kernel/src/config/config_by_k8s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::{cmp::Ordering, collections::HashMap, sync::Arc};

use itertools::Itertools;
use k8s_gateway_api::{Gateway, HttpRoute, HttpRouteFilter};
use k8s_openapi::api::core::v1::Secret;
use kube::{
api::ListParams,
runtime::{watcher, WatchStreamExt},
Expand All @@ -21,13 +20,13 @@ 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 crate::plugins::filters::header_modifier::SgFilterHeaderModifierKind;
use kernel_common::constants::{DEFAULT_NAMESPACE, GATEWAY_CLASS_NAME};
use kernel_common::constants::k8s_constants::{DEFAULT_NAMESPACE, GATEWAY_CLASS_NAME};
use kernel_common::gatewayapi_support_filter::SgFilterHeaderModifierKind;
use kernel_common::helper;
use kernel_common::helper::k8s_helper::{get_k8s_obj_unique, WarpKubeResult};
use kernel_common::inner_model::plugin_filter::SgHttpPathModifierType;
use kernel_common::inner_model::{
gateway::{SgGateway, SgListener, SgParameters, SgProtocol, SgTlsConfig, SgTlsMode},
gateway::{SgGateway, SgListener, SgParameters, SgProtocol, SgTlsConfig},
http_route::{
SgBackendRef, SgHttpHeaderMatch, SgHttpHeaderMatchType, SgHttpPathMatch, SgHttpPathMatchType, SgHttpQueryMatch, SgHttpQueryMatchType, SgHttpRoute, SgHttpRouteMatch,
SgHttpRouteRule,
Expand Down Expand Up @@ -854,8 +853,8 @@ fn convert_filters(filters: Option<Vec<HttpRouteFilter>>) -> Option<Vec<SgRouteF
SgRouteFilter {
code: crate::plugins::filters::header_modifier::CODE.to_string(),
name: None,
spec: TardisFuns::json.obj_to_json(&crate::plugins::filters::header_modifier::SgFilterHeaderModifier {
kind: crate::plugins::filters::header_modifier::SgFilterHeaderModifierKind::Request,
spec: TardisFuns::json.obj_to_json(&kernel_common::gatewayapi_support_filter::SgFilterHeaderModifier {
kind: kernel_common::gatewayapi_support_filter::SgFilterHeaderModifierKind::Request,
sets: if sg_sets.is_empty() { None } else { Some(sg_sets) },
remove: request_header_modifier.remove,
})?,
Expand All @@ -876,8 +875,8 @@ fn convert_filters(filters: Option<Vec<HttpRouteFilter>>) -> Option<Vec<SgRouteF
SgRouteFilter {
code: crate::plugins::filters::header_modifier::CODE.to_string(),
name: None,
spec: TardisFuns::json.obj_to_json(&crate::plugins::filters::header_modifier::SgFilterHeaderModifier {
kind: crate::plugins::filters::header_modifier::SgFilterHeaderModifierKind::Response,
spec: TardisFuns::json.obj_to_json(&kernel_common::gatewayapi_support_filter::SgFilterHeaderModifier {
kind: kernel_common::gatewayapi_support_filter::SgFilterHeaderModifierKind::Response,
sets: if sg_sets.is_empty() { None } else { Some(sg_sets) },
remove: response_header_modifier.remove,
})?,
Expand Down Expand Up @@ -950,7 +949,7 @@ fn convert_to_kube_filters(filters: Option<Vec<SgRouteFilter>>) -> TardisResult<
let http_route_filter = match filter.code.as_str() {
crate::plugins::filters::header_modifier::CODE => {
let header_modifier = TardisFuns::json
.json_to_obj::<crate::plugins::filters::header_modifier::SgFilterHeaderModifier>(filter.spec)
.json_to_obj::<kernel_common::gatewayapi_support_filter::SgFilterHeaderModifier>(filter.spec)
.map_err(|error| TardisError::bad_request(&format!("[SG.Config] HttpRouteFilter [code={}] config parsing error: {error} ", filter.code), ""))?;
match header_modifier.kind {
SgFilterHeaderModifierKind::Request => HttpRouteFilter::RequestHeaderModifier {
Expand Down
32 changes: 10 additions & 22 deletions kernel/src/plugins/filters/header_modifier.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
use async_trait::async_trait;
use http::HeaderName;
use std::collections::HashMap;

use super::{SgPluginFilter, SgPluginFilterInitDto, SgRoutePluginContext};
use super::{SgPluginFilter, SgPluginFilterAccept, SgPluginFilterInitDto, SgPluginFilterKind, SgRoutePluginContext};
use crate::def_filter;
use async_trait::async_trait;
use http::HeaderName;
use kernel_common::gatewayapi_support_filter::{SgFilterHeaderModifier, SgFilterHeaderModifierKind};
use serde::{Deserialize, Serialize};
use tardis::basic::{error::TardisError, result::TardisResult};
use tardis::basic::error::TardisError;
use tardis::basic::result::TardisResult;

def_filter!("header_modifier", SgFilterHeaderModifierDef, SgFilterHeaderModifier);

#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct SgFilterHeaderModifier {
pub kind: SgFilterHeaderModifierKind,
pub sets: Option<HashMap<String, String>>,
pub remove: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Default)]
pub enum SgFilterHeaderModifierKind {
#[default]
Request,
Response,
}

#[async_trait]
impl SgPluginFilter for SgFilterHeaderModifier {
fn accept(&self) -> super::SgPluginFilterAccept {
super::SgPluginFilterAccept {
kind: vec![super::SgPluginFilterKind::Http],
fn accept(&self) -> SgPluginFilterAccept {
SgPluginFilterAccept {
kind: vec![SgPluginFilterKind::Http],
..Default::default()
}
}
Expand Down Expand Up @@ -78,12 +66,12 @@ impl SgPluginFilter for SgFilterHeaderModifier {
}

#[cfg(test)]

mod tests {

use super::*;
use http::{HeaderMap, Method, StatusCode, Uri, Version};
use hyper::Body;
use kernel_common::gatewayapi_support_filter::{SgFilterHeaderModifier, SgFilterHeaderModifierKind};
use std::collections::HashMap;
use tardis::tokio;

Expand Down

0 comments on commit 4189a1b

Please sign in to comment.