mz_deploy/secret_resolver/
json_field.rs1pub(super) fn extract_json_field(
20 secret_string: &str,
21 json_key: &str,
22 secret_name: &str,
23) -> Result<String, String> {
24 let value: serde_json::Value = serde_json::from_str(secret_string).map_err(|e| {
25 format!(
26 "secret '{}' is not valid JSON; cannot extract field '{}': {}",
27 secret_name, json_key, e
28 )
29 })?;
30
31 let field = value
32 .get(json_key)
33 .ok_or_else(|| format!("secret '{}' has no field '{}'", secret_name, json_key))?;
34
35 match field {
36 serde_json::Value::String(s) => Ok(s.clone()),
37 _ => Err(format!(
38 "field '{}' in secret '{}' is not a string",
39 json_key, secret_name
40 )),
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[mz_ore::test]
49 fn extract_json_field_returns_string_value() {
50 let secret = r#"{"username":"alice","password":"s3cr3t"}"#;
51 assert_eq!(
52 extract_json_field(secret, "password", "rds-creds").unwrap(),
53 "s3cr3t"
54 );
55 assert_eq!(
56 extract_json_field(secret, "username", "rds-creds").unwrap(),
57 "alice"
58 );
59 }
60
61 #[mz_ore::test]
62 fn extract_json_field_errors_on_missing_key() {
63 let secret = r#"{"username":"alice"}"#;
64 let err = extract_json_field(secret, "password", "rds-creds").unwrap_err();
65 assert!(err.contains("rds-creds"));
66 assert!(err.contains("password"));
67 }
68
69 #[mz_ore::test]
70 fn extract_json_field_errors_on_non_string_value() {
71 let secret = r#"{"port":5432}"#;
72 let err = extract_json_field(secret, "port", "rds-creds").unwrap_err();
73 assert!(err.contains("rds-creds"));
74 assert!(err.contains("port"));
75 assert!(err.contains("not a string"));
76 }
77
78 #[mz_ore::test]
79 fn extract_json_field_errors_on_invalid_json() {
80 let secret = "not json at all";
81 let err = extract_json_field(secret, "password", "rds-creds").unwrap_err();
82 assert!(err.contains("rds-creds"));
83 assert!(err.contains("not valid JSON"));
84 }
85}