Skip to content

Commit 0f0c60e

Browse files
committed
add some configuration checking + normalization
Signed-off-by: Lance-Drane <[email protected]>
1 parent 3176394 commit 0f0c60e

File tree

10 files changed

+86
-17
lines changed

10 files changed

+86
-17
lines changed

.dockerignore

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
/target
2-
*.tmp
3-
*.log
4-
Dockerfile
5-
.dockerignore
1+
*
2+
!proxy-http-client
3+
!proxy-http-server
4+
!shared-deps
5+
!Cargo.lock
6+
!Cargo.toml
7+
!rust-toolchain.toml

charts/proxy-http-client/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: v2
22
name: proxy-http-client
33
description: "Subscribe to events over HTTP from a proxy-http-server instance, and publish them on a local broker"
4-
version: 0.1.0
4+
version: 0.1.1
55
dependencies:
66
- name: common
77
repository: oci://registry-1.docker.io/bitnamicharts

charts/proxy-http-client/values.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ serviceAccount:
128128

129129
app:
130130
log_level: "info"
131-
topic_prefix: "" # i.e. "organization.facility.system.", you should consciously set this value. It MUST end with a "."
131+
topic_prefix: "" # i.e. "organization.facility.system.", you should consciously set this value.
132132
other_proxy:
133-
url: "" # this should not include the path or a trailing slash
133+
url: "" # this should not include the path
134134
username: "" # needed credential for clients calling HTTP endpoints other than /healthcheck
135135
password: "" # needed credential for clients calling HTTP endpoints other than /healthcheck
136136
broker:

charts/proxy-http-server/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: v2
22
name: proxy-http-server
33
description: "Subscribe to broker messages and broadcast them to HTTP listeners"
4-
version: 0.1.0
4+
version: 0.1.1
55
dependencies:
66
- name: common
77
repository: oci://registry-1.docker.io/bitnamicharts

charts/proxy-http-server/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ serviceAccount:
160160

161161
app:
162162
log_level: "info"
163-
topic_prefix: "" # i.e. "organization.facility.system.", you should consciously set this value. It MUST end with a "."
163+
topic_prefix: "" # i.e. "organization.facility.system.", you should consciously set this value.
164164
username: "" # needed credential for clients calling HTTP endpoints other than /healthcheck
165165
password: "" # needed credential for clients calling HTTP endpoints other than /healthcheck
166166
broker:

proxy-http-client/conf.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# local development config file for the HTTP client
22
other_proxy:
3-
url: "http://localhost:8080" # do not include the trailing "/" or any part of the path
3+
url: "http://localhost:8080/" # do not include the path, trailing slash is optional
44
username: dummy_username
55
password: dummy_password
66
broker:
@@ -10,7 +10,6 @@ broker:
1010
# note: differs from other config file (two separate brokers used)
1111
port: 5673
1212
# use amqp topic notation, note that the system is different from the other configuration
13-
# TODO: current implementation requires this to end with a "." character, this should be fixed...
14-
topic_prefix: "organization.facility.system2." # CHANGE THIS PER DEPLOYMENT!!!
13+
topic_prefix: "organization.facility.system2" # CHANGE THIS PER DEPLOYMENT!!!
1514
log_level: "debug"
1615
production: false

proxy-http-client/src/configuration.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
/// 5) Additional logic can be found in shared-deps/src/configuration.rs
77
use secrecy::SecretString;
88

9-
use intersect_ingress_proxy_common::configuration::{BrokerSettings, LogLevel};
9+
use intersect_ingress_proxy_common::configuration::{
10+
deserialize_enforce_topic_prefixes, deserialize_trim_trailing_slash, BrokerSettings, LogLevel,
11+
};
1012

1113
#[derive(serde::Deserialize, Clone, Debug)]
1214
pub struct ExternalProxy {
15+
#[serde(deserialize_with = "deserialize_trim_trailing_slash")]
1316
/// URL for the other ingress proxy we are communicating with
1417
pub url: String,
1518
/// Basic authentication credentials for the other proxy
@@ -28,6 +31,7 @@ pub struct Settings {
2831
pub log_level: LogLevel,
2932
/// set to true for developer-unfriendly settings (currently just log formats)
3033
pub production: bool,
34+
#[serde(deserialize_with = "deserialize_enforce_topic_prefixes")]
3135
/// this should only contain the SYSTEM prefix, i.e. "organization.facility.system."
3236
pub topic_prefix: String,
3337
}

proxy-http-server/conf.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ broker:
77
# note: differs from other config file (two separate brokers used)
88
port: 5672
99
# use amqp topic notation
10-
# TODO: current implementation requires this to end with a "." character, this should be fixed...
11-
topic_prefix: "organization.facility.system." # CHANGE THIS PER DEPLOYMENT!!!
10+
topic_prefix: "organization.facility.system" # CHANGE THIS PER DEPLOYMENT!!!
1211
log_level: "debug"
1312
username: dummy_username
1413
password: dummy_password

proxy-http-server/src/configuration.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use secrecy::SecretString;
88
use serde_aux::field_attributes::deserialize_number_from_string;
99

10-
use intersect_ingress_proxy_common::configuration::{BrokerSettings, LogLevel};
10+
use intersect_ingress_proxy_common::configuration::{
11+
deserialize_enforce_topic_prefixes, BrokerSettings, LogLevel,
12+
};
1113

1214
#[derive(serde::Deserialize, Clone)]
1315
pub struct Settings {
@@ -18,6 +20,7 @@ pub struct Settings {
1820
pub app_port: u16,
1921
/// log level of the entire application
2022
pub log_level: LogLevel,
23+
#[serde(deserialize_with = "deserialize_enforce_topic_prefixes")]
2124
/// this should only contain the SYSTEM prefix, i.e. "organization.facility.system."
2225
pub topic_prefix: String,
2326
/// username for Basic Authentication

shared-deps/src/configuration.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::{fmt::Display, str::FromStr};
55

66
use secrecy::SecretString;
7+
use serde::{de::Error as deError, Deserialize, Deserializer};
78
use serde_aux::field_attributes::deserialize_number_from_string;
89

910
#[derive(serde::Deserialize, Clone, Debug)]
@@ -55,6 +56,67 @@ impl Display for LogLevel {
5556
}
5657
}
5758

59+
/// when deserializing, strip out any trailing slashes from the end (useful for URLs)
60+
pub fn deserialize_trim_trailing_slash<'de, D>(deserializer: D) -> Result<String, D::Error>
61+
where
62+
D: Deserializer<'de>,
63+
{
64+
let mut base: String = Deserialize::deserialize(deserializer)?;
65+
if base.ends_with("/") {
66+
base.pop();
67+
}
68+
Ok(base)
69+
}
70+
71+
/// custom deserializer which enforces and normalizes system names
72+
pub fn deserialize_enforce_topic_prefixes<'de, D>(deserializer: D) -> Result<String, D::Error>
73+
where
74+
D: Deserializer<'de>,
75+
{
76+
let mut base: String = Deserialize::deserialize(deserializer)?;
77+
78+
// TODO will need to update this logic later, when we reduce the namespacing as part of a new INTERSECT release
79+
let mut period_count = 0_u16;
80+
for character in base.chars() {
81+
if character == '-' || character.is_ascii_digit() || character.is_ascii_lowercase() {
82+
continue;
83+
} else if character == '.' {
84+
period_count += 1;
85+
} else {
86+
return Err(deError::custom(format!(
87+
"topic_prefix: Invalid character detected: {}",
88+
character
89+
)));
90+
}
91+
}
92+
93+
match period_count {
94+
2 => {
95+
if base.ends_with(".") {
96+
Err(deError::custom(
97+
"topic_prefix: 3 levels of namespacing expected but only 2 provided",
98+
))
99+
} else {
100+
base += ".";
101+
Ok(base)
102+
}
103+
}
104+
3 => {
105+
if base.ends_with(".") {
106+
Ok(base)
107+
} else {
108+
Err(deError::custom(
109+
"topic_prefix: 3 levels of namespacing expected but 4 provided",
110+
))
111+
}
112+
}
113+
c => Err(deError::custom(format!(
114+
"topic_prefix: Too many periods ({})",
115+
c
116+
))),
117+
}
118+
}
119+
58120
/// Common logic for obtaining a configuration of type T
59121
///
60122
/// Rules:

0 commit comments

Comments
 (0)