Skip to content

Commit

Permalink
Merge pull request #3278 from jarhodes314/feat/profiles-ux-improvments
Browse files Browse the repository at this point in the history
feat: further improvements to cloud-profile UX
  • Loading branch information
jarhodes314 authored Dec 13, 2024
2 parents 44a56e3 + c077ab0 commit be7cd20
Show file tree
Hide file tree
Showing 32 changed files with 1,175 additions and 377 deletions.
4 changes: 4 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

0 comments on commit be7cd20

Please sign in to comment.