Watch
0
0
Fork
You've already forked hyperhive
0

logs and metrics permissions, tolerant record decode, hive capabilities

This commit is contained in:
atlas 2026-11-01 17:40:09 +01:00
commit 04598542b6

View file

@ -69,7 +69,13 @@ pub const IMPORT_REPLY_DEADLINE: std::time::Duration = std::time::Duration::from
/// older hive the fields it knows.
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct AgentPermissions {
#[serde(default, skip_serializing_if = "Option::is_none")]
/// Names this build does not know are skipped on decode, so a permission
/// a newer controller adds does not cost this reader the record.
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "hive_types::deserialize_known"
)]
pub permissions: Option<Vec<hive_types::Permission>>,
/// Whether the agent's traffic leaves the host unfiltered. Absent is "on":
/// an agent whose key predates the field keeps the open access it had, and
@ -155,6 +161,23 @@ mod tests {
assert_eq!(ruth.permissions, Some(vec![Permission::ManageRootAgent]));
}
/// A record naming a permission this build does not know still decodes,
/// with that name skipped and the other fields intact: the reader holds
/// what it knows instead of nothing.
#[test]
fn a_record_with_an_unknown_permission_still_decodes() {
use hive_types::Permission;
let record: AgentPermissions = serde_json::from_str(
r#"{"permissions":["messaging","from-the-future","logs"],"unrestricted_internet":false}"#,
)
.unwrap();
assert_eq!(
record.permissions,
Some(vec![Permission::Messaging, Permission::Logs])
);
assert_eq!(record.unrestricted_internet, Some(false));
}
/// The flag is left out when unset, so a record that never named it
/// encodes as before, and an explicit `false` is kept on the wire.
#[test]