Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support multiple cloud profiles #3278

Merged
merged 17 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=syslog.target network.target mosquitto.service
[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper aws@%i
ExecStart=/usr/bin/tedge-mapper aws --profile %i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5
Expand Down
2 changes: 1 addition & 1 deletion configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=syslog.target network.target mosquitto.service
[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper az@%i
ExecStart=/usr/bin/tedge-mapper az --profile %i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5
Expand Down
2 changes: 1 addition & 1 deletion configuration/init/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ After=syslog.target network.target mosquitto.service
[Service]
User=tedge
ExecStartPre=+-/usr/bin/tedge init
ExecStart=/usr/bin/tedge-mapper c8y@%i
ExecStart=/usr/bin/tedge-mapper c8y --profile %i
Restart=on-failure
RestartPreventExitStatus=255
RestartSec=5
Expand Down
98 changes: 97 additions & 1 deletion crates/common/tedge_config/src/tedge_config_cli/figment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl TEdgeEnv {

fn provider(&self) -> figment::providers::Env {
static WARNINGS: Lazy<Mutex<HashSet<String>>> = Lazy::new(<_>::default);
figment::providers::Env::prefixed(self.prefix).ignore(&["CONFIG_DIR"]).map(move |name| {
figment::providers::Env::prefixed(self.prefix).ignore(&["CONFIG_DIR", "CLOUD_PROFILE"]).map(move |name| {
let lowercase_name = name.as_str().to_ascii_lowercase();
Uncased::new(
tracing::subscriber::with_default(
Expand Down Expand Up @@ -237,6 +237,7 @@ mod tests {
use std::path::PathBuf;

use serde::Deserialize;
use tedge_config_macros::define_tedge_config;

use super::*;

Expand All @@ -259,6 +260,7 @@ mod tests {
Ok(())
})
}

#[test]
fn environment_variables_override_config_file() {
#[derive(Deserialize)]
Expand Down Expand Up @@ -376,4 +378,98 @@ mod tests {
Ok(())
})
}

#[test]
fn environment_variables_can_override_profiled_configurations() {
use crate::AppendRemoveItem;
use crate::ReadError;
use tedge_config_macros::*;

define_tedge_config!(
#[tedge_config(multi)]
c8y: {
url: String,
}
);

figment::Jail::expect_with(|jail| {
jail.create_file(
"tedge.toml",
r#"
[c8y.profiles.test]
url = "test.c8y.io"
"#,
)?;

jail.set_env("TEDGE_C8Y_PROFILES_TEST_URL", "override.c8y.io");

let dto =
extract_data::<TEdgeConfigDto, FileAndEnvironment>(&PathBuf::from("tedge.toml"))
.unwrap()
.0;
assert_eq!(
dto.c8y.try_get(Some("test"), "c8y").unwrap().url.as_deref(),
Some("override.c8y.io")
);
Ok(())
})
}

#[test]
fn environment_variable_profile_warnings_use_key_with_correct_format() {
use crate::AppendRemoveItem;
use crate::ReadError;
use tedge_config_macros::*;

define_tedge_config!(
#[tedge_config(multi)]
c8y: {
url: String,
}
);

figment::Jail::expect_with(|jail| {
jail.set_env("TEDGE_C8Y_PROFILES_TEST_UNKNOWN", "override.c8y.io");

let warnings =
extract_data::<TEdgeConfigDto, FileAndEnvironment>(&PathBuf::from("tedge.toml"))
.unwrap()
.1;
assert_eq!(
warnings.0,
["Unknown configuration field \"c8y_profiles_test_unknown\" from environment variable TEDGE_C8Y_PROFILES_TEST_UNKNOWN"]
);
Ok(())
})
}

#[test]
fn toml_profile_warnings_use_key_with_correct_format() {
use crate::AppendRemoveItem;
use crate::ReadError;
use tedge_config_macros::*;

define_tedge_config!(
#[tedge_config(multi)]
c8y: {
url: String,
}
);

figment::Jail::expect_with(|jail| {
jail.create_file(
"tedge.toml",
r#"
[c8y.profiles.test]
unknown = "test.c8y.io"
"#,
)?;
let warnings =
extract_data::<TEdgeConfigDto, FileAndEnvironment>(&PathBuf::from("tedge.toml"))
.unwrap()
.1;
assert!(dbg!(warnings.0.first().unwrap()).contains("c8y.profiles.test.unknown"));
Ok(())
})
}
}
78 changes: 20 additions & 58 deletions crates/common/tedge_config_macros/examples/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,6 @@ define_tedge_config! {
#[tedge_config(example = "true", default(value = true))]
use_operation_id: bool,
},

#[tedge_config(multi)]
something: {
test: String,
}
},
}

Expand All @@ -64,83 +59,49 @@ fn url_for<'a>(reader: &'a TEdgeConfigReader, o: Option<&str>) -> &'a str {
}

fn main() {
let single_c8y_toml = "c8y.url = \"https://example.com\"";
let single_c8y_dto = toml::from_str(single_c8y_toml).unwrap();
let single_c8y_reader = TEdgeConfigReader::from_dto(&single_c8y_dto, &TEdgeConfigLocation);
assert_eq!(url_for(&single_c8y_reader, None), "https://example.com");

let multi_c8y_toml = "c8y.cloud.url = \"https://cloud.example.com\"\nc8y.edge.url = \"https://edge.example.com\"";
let multi_c8y_dto = toml::from_str(multi_c8y_toml).unwrap();
let multi_c8y_reader = TEdgeConfigReader::from_dto(&multi_c8y_dto, &TEdgeConfigLocation);
let c8y_toml = "c8y.url = \"https://example.com\"\nc8y.profiles.cloud.url = \"https://cloud.example.com\"\nc8y.profiles.edge.url = \"https://edge.example.com\"";
let c8y_dto = toml::from_str(c8y_toml).unwrap();
let c8y_reader = TEdgeConfigReader::from_dto(&c8y_dto, &TEdgeConfigLocation);
assert_eq!(
url_for(&multi_c8y_reader, Some("cloud")),
url_for(&c8y_reader, Some("cloud")),
"https://cloud.example.com"
);
assert_eq!(
url_for(&multi_c8y_reader, Some("edge")),
url_for(&c8y_reader, Some("edge")),
"https://edge.example.com"
);

assert_eq!(
single_c8y_reader
.c8y
.try_get(Some("cloud"))
.unwrap_err()
.to_string(),
"You are trying to access a profile `cloud` of c8y, but profiles are not enabled for c8y"
);
assert_eq!(
multi_c8y_reader
c8y_reader
.c8y
.try_get(Some("unknown"))
.unwrap_err()
.to_string(),
"Unknown profile `unknown` for the multi-profile property c8y"
);
assert_eq!(
multi_c8y_reader
.c8y
.try_get::<&str>(None)
.unwrap_err()
.to_string(),
"A profile is required for the multi-profile property c8y"
);
assert_eq!(url_for(&c8y_reader, None), "https://example.com",);

assert_eq!(
"c8y.url".parse::<ReadableKey>().unwrap(),
ReadableKey::C8yUrl(None)
);
assert_eq!(
"c8y.cloud.url".parse::<ReadableKey>().unwrap(),
"c8y.profiles.cloud.url".parse::<ReadableKey>().unwrap(),
ReadableKey::C8yUrl(Some("cloud".to_owned()))
);
assert_eq!(
"c8y.cloud.something.test".parse::<ReadableKey>().unwrap(),
ReadableKey::C8ySomethingTest(Some("cloud".to_owned()), None)
);
assert_eq!(
"c8y.cloud.something.thing.test"
.parse::<ReadableKey>()
.unwrap(),
ReadableKey::C8ySomethingTest(Some("cloud".to_owned()), Some("thing".to_owned()))
);
assert_eq!(
"c8y.something.thing.test".parse::<ReadableKey>().unwrap(),
ReadableKey::C8ySomethingTest(None, Some("thing".to_owned()))
);
assert_eq!(
"c8y.cloud.not_a_real_key"
"c8y.profiles.cloud.not_a_real_key"
.parse::<ReadableKey>()
.unwrap_err()
.to_string(),
"Unknown key: 'c8y.cloud.not_a_real_key'"
"Unknown key: 'c8y.profiles.cloud.not_a_real_key'"
);
assert_eq!(
"c8y.urll".parse::<ReadableKey>().unwrap_err().to_string(),
"Unknown key: 'c8y.urll'"
);

let mut keys = multi_c8y_reader
let mut keys = c8y_reader
.readable_keys()
.map(|r| r.to_string())
.collect::<Vec<_>>();
Expand All @@ -149,14 +110,15 @@ fn main() {
assert_eq!(
keys,
[
"c8y.cloud.http",
"c8y.cloud.smartrest.use_operation_id",
"c8y.cloud.something.test",
"c8y.cloud.url",
"c8y.edge.http",
"c8y.edge.smartrest.use_operation_id",
"c8y.edge.something.test",
"c8y.edge.url"
"c8y.http",
"c8y.smartrest.use_operation_id",
"c8y.url",
"c8y.profiles.cloud.http",
"c8y.profiles.cloud.smartrest.use_operation_id",
"c8y.profiles.cloud.url",
"c8y.profiles.edge.http",
"c8y.profiles.edge.smartrest.use_operation_id",
"c8y.profiles.edge.url"
]
);
}
2 changes: 2 additions & 0 deletions crates/common/tedge_config_macros/impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ syn = { workspace = true }
[dev-dependencies]
pretty_assertions = { workspace = true }
prettyplease = { workspace = true }
regex = { workspace = true }
test-case = { workspace = true }

[lints]
workspace = true
Loading
Loading