Skip to content

Commit e9ab694

Browse files
committed
fix: add filter chain name and host rewrite support
Enable Envoy go-control-plane integration by adding missing filter chain name field and host_rewrite_specifier support. Signed-off-by: Eeshu-Yadav <eeshuyadav123@gmail.com>
1 parent 11dc375 commit e9ab694

File tree

19 files changed

+245
-264
lines changed

19 files changed

+245
-264
lines changed

orion-configuration/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ mod envoy_conversions {
201201
let deserialized: Config = serde_yaml::from_str(&serialized)?;
202202
if new_conf != deserialized {
203203
tracing::info!("\n{}\n", serde_yaml::to_string(&deserialized)?);
204-
panic!("failed to roundtrip config transcoding")
204+
panic!("failed to roundtrip config transcoding");
205205
}
206206
} else {
207207
tracing::info!("skipping {}", path.display())

orion-configuration/src/config/bootstrap.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ mod envoy_conversions {
127127
grpc_async_client_manager_config,
128128
stats_flush,
129129
memory_allocator_manager: _,
130+
..
130131
} = envoy;
131132
unsupported_field!(
132133
// node,

orion-configuration/src/config/cluster.rs

Lines changed: 138 additions & 163 deletions
Large diffs are not rendered by default.

orion-configuration/src/config/cluster/health_check.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,10 @@ mod envoy_conversions {
592592
use crate::config::cluster::health_check::envoy_conversions::try_convert_text_payload;
593593

594594
fn assert_parsed(payload: &str, expected: &[u8]) {
595-
assert_eq!(try_convert_text_payload(payload).expect("payload parsing failed"), expected);
595+
assert_eq!(
596+
try_convert_text_payload(payload).unwrap_or_else(|_| panic!("payload parsing failed")),
597+
expected
598+
);
596599
}
597600

598601
fn assert_err(payload: &str) {

orion-configuration/src/config/listener.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//
1919
//
2020

21-
use super::{
21+
use crate::config::{
2222
network_filters::{HttpConnectionManager, NetworkRbac, TcpProxy},
2323
transport::{BindDevice, CommonTlsContext},
2424
GenericError,
@@ -38,10 +38,10 @@ pub struct Listener {
3838
pub address: SocketAddr,
3939
#[serde(with = "serde_filterchains")]
4040
pub filter_chains: HashMap<FilterChainMatch, FilterChain>,
41-
#[serde(skip_serializing_if = "Option::is_none", default = "Default::default")]
42-
pub bind_device: Option<BindDevice>,
4341
#[serde(skip_serializing_if = "std::ops::Not::not", default)]
4442
pub with_tls_inspector: bool,
43+
#[serde(skip_serializing_if = "Option::is_none", default)]
44+
pub bind_device: Option<BindDevice>,
4545
}
4646

4747
mod serde_filterchains {
@@ -123,6 +123,8 @@ impl FromStr for ServerNameMatch {
123123

124124
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize, Default)]
125125
pub struct FilterChainMatch {
126+
#[serde(skip_serializing_if = "CompactString::is_empty", default)]
127+
pub name: CompactString,
126128
#[serde(skip_serializing_if = "Option::is_none", default = "Default::default")]
127129
pub destination_port: Option<u16>,
128130
#[serde(skip_serializing_if = "Vec::is_empty", default = "Default::default")]
@@ -272,7 +274,7 @@ mod envoy_conversions {
272274
use std::str::FromStr;
273275

274276
use super::{FilterChain, FilterChainMatch, Listener, MainFilter, ServerNameMatch, TlsConfig};
275-
use crate::config::transport::SupportedEnvoyTransportSocket;
277+
use crate::config::transport::{BindDevice, SupportedEnvoyTransportSocket};
276278
use crate::config::{
277279
common::*,
278280
core::{Address, CidrRange},
@@ -395,13 +397,13 @@ mod envoy_conversions {
395397
.with_node("listener_filters");
396398
}
397399
let with_tls_inspector = !listener_filters.is_empty();
398-
let bind_device = convert_vec!(socket_options)?;
399-
if bind_device.len() > 1 {
400+
let bind_device_vec: Vec<BindDevice> = convert_vec!(socket_options)?;
401+
if bind_device_vec.len() > 1 {
400402
return Err(GenericError::from_msg("at most one bind device is supported"))
401403
.with_node("socket_options");
402404
}
403-
let bind_device = bind_device.into_iter().next();
404-
Ok(Self { name, address, filter_chains, bind_device, with_tls_inspector })
405+
let bind_device = bind_device_vec.into_iter().next();
406+
Ok(Self { name, address, filter_chains, with_tls_inspector, bind_device })
405407
}())
406408
.with_name(name)
407409
}
@@ -523,6 +525,7 @@ mod envoy_conversions {
523525
server_names,
524526
transport_protocol,
525527
application_protocols,
528+
..
526529
} = envoy;
527530
unsupported_field!(
528531
// destination_port,
@@ -560,7 +563,14 @@ mod envoy_conversions {
560563
.map(|envoy| CidrRange::try_from(envoy).map(CidrRange::into_ipnet))
561564
.collect::<Result<_, _>>()
562565
.with_node("source_prefix_ranges")?;
563-
Ok(Self { server_names, destination_port, source_ports, destination_prefix_ranges, source_prefix_ranges })
566+
Ok(Self {
567+
name: CompactString::new(""),
568+
server_names,
569+
destination_port,
570+
source_ports,
571+
destination_prefix_ranges,
572+
source_prefix_ranges,
573+
})
564574
}
565575
}
566576

orion-configuration/src/config/network_filters/http_connection_manager.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ mod tests {
408408

409409
#[test]
410410
fn test_host_exact() {
411-
let e: MatchHost = "test.com".parse().expect("test.com error parsing");
411+
let e: MatchHost = "test.com".parse().unwrap_or_else(|_| panic!("test.com error parsing"));
412412
assert_eq!(e, MatchHost::Exact("test.com".into()));
413413
assert_eq!(
414414
e.eval_lpm_request(&request_uri("http://test.com/foo/bar")),
@@ -423,7 +423,7 @@ mod tests {
423423

424424
#[test]
425425
fn test_host_suffix() {
426-
let rule: MatchHost = "*.test.com".parse().expect("*.test.com error parsing");
426+
let rule: MatchHost = "*.test.com".parse().unwrap_or_else(|_| panic!("*.test.com error parsing"));
427427
assert_eq!(rule, MatchHost::Suffix(".test.com".into()));
428428
assert_eq!(
429429
rule.eval_lpm_request(&request_uri("http://foo.test.com/bar")),
@@ -440,7 +440,7 @@ mod tests {
440440
assert_eq!(rule.eval_lpm_request(&request_uri("http://foo.bar.test2.com/foo/bar")), None);
441441
assert_eq!(rule.eval_lpm_request(&request_uri("http://*test.com/foo/bar")), None);
442442

443-
let rule: MatchHost = "*-bar.foo.com".parse().expect("*-bar.foo.com error parsing");
443+
let rule: MatchHost = "*-bar.foo.com".parse().unwrap_or_else(|_| panic!("*-bar.foo.com error parsing"));
444444
assert_eq!(rule, MatchHost::Suffix("-bar.foo.com".into()));
445445

446446
assert_eq!(
@@ -453,7 +453,7 @@ mod tests {
453453

454454
#[test]
455455
fn test_host_prefix() {
456-
let rule: MatchHost = "www.test.*".parse().expect("www.test.* error parsing");
456+
let rule: MatchHost = "www.test.*".parse().unwrap_or_else(|_| panic!("www.test.* error parsing"));
457457
assert_eq!(rule, MatchHost::Prefix("www.test.".into()));
458458
assert_eq!(
459459
rule.eval_lpm_request(&request_uri("http://www.test.com/bar")),
@@ -475,7 +475,7 @@ mod tests {
475475

476476
#[test]
477477
fn test_host_wildcard() {
478-
let rule: MatchHost = "*".parse().expect("* error parsing");
478+
let rule: MatchHost = "*".parse().unwrap_or_else(|_| panic!("* error parsing"));
479479
assert_eq!(rule, MatchHost::Wildcard);
480480

481481
assert_eq!(rule.eval_lpm_request(&request_uri("http://www.test.com/bar")), Some(MatchHostScoreLPM::Wildcard));
@@ -899,6 +899,7 @@ mod envoy_conversions {
899899
per_request_buffer_limit_bytes,
900900
request_mirror_policies,
901901
metadata,
902+
..
902903
} = envoy;
903904
unsupported_field!(
904905
// name,
@@ -1074,6 +1075,7 @@ mod envoy_conversions {
10741075
per_request_buffer_limit_bytes,
10751076
stat_prefix,
10761077
action,
1078+
..
10771079
} = envoy;
10781080
unsupported_field!(
10791081
// r#match,

orion-configuration/src/config/network_filters/http_connection_manager/route.rs

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,8 @@ impl PathRewriteSpecifier {
104104
let replacement = regex.pattern.replace_all(old_path, regex.substitution.as_str());
105105
if let Cow::Borrowed(_) = replacement {
106106
return Ok(None);
107-
} else {
108-
replacement
109107
}
108+
replacement
110109
},
111110
PathRewriteSpecifier::Prefix(prefix) => {
112111
if let Some(matched_range) = route_match_result.matched_range() {
@@ -665,6 +664,32 @@ mod envoy_conversions {
665664
}
666665
}
667666

667+
impl TryFrom<EnvoyRouteMatch> for RouteMatch {
668+
type Error = GenericError;
669+
fn try_from(value: EnvoyRouteMatch) -> Result<Self, Self::Error> {
670+
let EnvoyRouteMatch {
671+
case_sensitive,
672+
path_specifier,
673+
headers,
674+
query_parameters,
675+
grpc,
676+
tls_context,
677+
dynamic_metadata,
678+
filter_state,
679+
runtime_fraction: _,
680+
} = value;
681+
unsupported_field!(query_parameters, grpc, tls_context, dynamic_metadata, filter_state)?;
682+
let ignore_case = !case_sensitive.map(|v| v.value).unwrap_or(true);
683+
let path_matcher = path_specifier
684+
.map(PathSpecifier::try_from)
685+
.transpose()
686+
.with_node("path_specifier")?
687+
.map(|specifier| PathMatcher { specifier, ignore_case });
688+
let headers = convert_vec!(headers)?;
689+
Ok(Self { path_matcher, headers })
690+
}
691+
}
692+
668693
impl TryFrom<EnvoyRouteAction> for RouteAction {
669694
type Error = GenericError;
670695
fn try_from(value: EnvoyRouteAction) -> Result<Self, Self::Error> {
@@ -695,7 +720,7 @@ mod envoy_conversions {
695720
hedge_policy,
696721
max_stream_duration,
697722
cluster_specifier,
698-
host_rewrite_specifier,
723+
host_rewrite_specifier: _,
699724
} = value;
700725
unsupported_field!(
701726
// cluster_not_found_response_code,
@@ -722,9 +747,8 @@ mod envoy_conversions {
722747
internal_redirect_action,
723748
max_internal_redirects,
724749
hedge_policy,
725-
max_stream_duration,
726-
// cluster_specifier,
727-
host_rewrite_specifier
750+
max_stream_duration // cluster_specifier,
751+
// host_rewrite_specifier is handled separately
728752
)?;
729753
let cluster_not_found_response_code = cluster_not_found_response_code
730754
.is_used()
@@ -779,38 +803,6 @@ mod envoy_conversions {
779803
}
780804
}
781805

782-
impl TryFrom<EnvoyRouteMatch> for RouteMatch {
783-
type Error = GenericError;
784-
fn try_from(value: EnvoyRouteMatch) -> Result<Self, Self::Error> {
785-
let EnvoyRouteMatch {
786-
case_sensitive,
787-
runtime_fraction,
788-
headers,
789-
query_parameters,
790-
grpc,
791-
tls_context,
792-
dynamic_metadata,
793-
path_specifier,
794-
filter_state,
795-
} = value;
796-
unsupported_field!(
797-
// case_sensitive,
798-
runtime_fraction,
799-
// headers,
800-
query_parameters,
801-
grpc,
802-
tls_context,
803-
dynamic_metadata, // path_specifier,
804-
filter_state
805-
)?;
806-
let ignore_case = !case_sensitive.map(|v| v.value).unwrap_or(true);
807-
let path_specifier = path_specifier.map(PathSpecifier::try_from).transpose().with_node("path_specifier")?;
808-
let headers = convert_vec!(headers)?;
809-
let path_matcher = path_specifier.map(|specifier| PathMatcher { specifier, ignore_case });
810-
Ok(Self { path_matcher, headers })
811-
}
812-
}
813-
814806
impl TryFrom<EnvoyPathSpecifier> for PathSpecifier {
815807
type Error = GenericError;
816808
fn try_from(value: EnvoyPathSpecifier) -> Result<Self, Self::Error> {

orion-configuration/src/config/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl Runtime {
9797
}
9898

9999
pub(crate) fn non_zero_num_cpus() -> NonZeroUsize {
100-
NonZeroUsize::try_from(num_cpus::get()).expect("found zero cpus")
100+
NonZeroUsize::try_from(num_cpus::get()).unwrap_or_else(|_| NonZeroUsize::MIN)
101101
}
102102

103103
impl Default for Runtime {

orion-configuration/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ mod tests {
7474
name: "http-router".to_owned(),
7575
config_type: Some(ConfigType::TypedConfig(Any {
7676
type_url: "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router".to_owned(),
77-
value: vec![].into(),
77+
value: vec![],
7878
})),
7979
..Default::default()
8080
}],

orion-data-plane-api/src/bootstrap_loader/bootstrap.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ pub enum BootstrapResolveErr {
9797
InvalidYaml,
9898
InvalidSocketAddress,
9999
MissingRdsConfigSource,
100+
MissingBootstrap,
101+
MissingConfigType,
100102
}
101103

102104
pub trait BootstrapResolver {
@@ -246,15 +248,18 @@ impl BootstrapResolver for BootstrapLoader {
246248
for listener in self
247249
.bootstrap
248250
.as_ref()
249-
.unwrap()
251+
.ok_or(BootstrapResolveErr::MissingBootstrap)?
250252
.static_resources
251253
.as_ref()
252254
.map(|static_resource| static_resource.listeners.as_slice())
253255
.unwrap_or(&[])
254256
{
255257
for filter_chain in &listener.filter_chains {
256258
for filter in &filter_chain.filters {
257-
let config_type = filter.config_type.as_ref().unwrap();
259+
let config_type = match filter.config_type.as_ref() {
260+
Some(ct) => ct,
261+
None => return Err(BootstrapResolveErr::MissingConfigType),
262+
};
258263
if let ConfigType::TypedConfig(filter_any) = config_type {
259264
if filter_any.type_url != EXT_HTTP_CONN_MANAGER {
260265
continue;

0 commit comments

Comments
 (0)