Watch
0
0
Fork
You've already forked hyperhive
0

swarm: unrestricted_internet flag on the agent permissions record, unset reads as on, create writes false

This commit is contained in:
atlas 2026-10-27 11:29:06 +01:00 • committed by mara
commit 8699857024

View file

@ -45,9 +45,14 @@ pub(crate) fn get(target: &Target, agent: &str) -> Result<()> {
/// Run `swarmctl agent permissions set`: store the given permissions, which
/// replace the agent's record whole.
pub(crate) fn set(target: &Target, agent: &str, permissions: &[String]) -> Result<()> {
pub(crate) fn set(
target: &Target,
agent: &str,
permissions: &[String],
unrestricted_internet: Option<bool>,
) -> Result<()> {
let uri = member(agent)?;
let wanted = with_permissions(permissions)?;
let wanted = with_permissions(permissions, unrestricted_internet)?;
let stored: Permissions = runtime()?.block_on(send(
target,
hyper::Method::PUT,
@ -61,7 +66,10 @@ pub(crate) fn set(target: &Target, agent: &str, permissions: &[String]) -> Resul
/// The record granting `permissions`. An empty name, as `--permissions ''`
/// gives, is dropped, so that spelling grants nothing.
fn with_permissions(permissions: &[String]) -> Result<Permissions> {
fn with_permissions(
permissions: &[String],
unrestricted_internet: Option<bool>,
) -> Result<Permissions> {
let granted = permissions
.iter()
.filter(|name| !name.is_empty())
@ -69,6 +77,7 @@ fn with_permissions(permissions: &[String]) -> Result<Permissions> {
.collect::<Result<Vec<_>>>()?;
Ok(Permissions {
permissions: Some(granted),
unrestricted_internet,
})
}
@ -112,7 +121,12 @@ fn render(p: &Permissions) -> String {
.collect::<Vec<_>>()
.join(", "),
};
format!("permissions: {caps}\n")
let internet = match p.unrestricted_internet {
None => "(not set; unrestricted)",
Some(true) => "unrestricted",
Some(false) => "restricted",
};
format!("permissions: {caps}\nunrestricted_internet: {internet}\n")
}
#[cfg(test)]
@ -122,18 +136,48 @@ mod tests {
#[test]
fn get_tells_unset_from_none() {
let unset: Permissions = serde_json::from_str("{}").unwrap();
assert_eq!(render(&unset), "permissions: (not set; the default)\n");
assert_eq!(
render(&unset),
"permissions: (not set; the default)\nunrestricted_internet: (not set; unrestricted)\n"
);
let none: Permissions = serde_json::from_str(r#"{"permissions":[]}"#).unwrap();
assert_eq!(render(&none), "permissions: (none)\n");
assert_eq!(
render(&none),
"permissions: (none)\nunrestricted_internet: (not set; unrestricted)\n"
);
let ruth: Permissions =
serde_json::from_str(r#"{"permissions":["manage_root_agent"]}"#).unwrap();
assert_eq!(render(&ruth), "permissions: manage_root_agent\n");
assert_eq!(
render(&ruth),
"permissions: manage_root_agent\nunrestricted_internet: (not set; unrestricted)\n"
);
}
/// An explicit flag is shown and sent; left out it is not sent, so a `PUT`
/// keeps the stored one.
#[test]
fn the_internet_flag_is_sent_only_when_given() {
let off = with_permissions(&[], Some(false)).unwrap();
assert_eq!(
serde_json::to_string(&off).unwrap(),
r#"{"permissions":[],"unrestricted_internet":false}"#
);
assert_eq!(
render(&off),
"permissions: (none)\nunrestricted_internet: restricted\n"
);
let left_out = with_permissions(&[], None).unwrap();
assert!(
!serde_json::to_string(&left_out)
.unwrap()
.contains("internet")
);
}
/// `--permissions ''` stores an empty list, not one empty name.
#[test]
fn an_empty_list_flag_grants_nothing() {
let set = with_permissions(&[String::new()]).unwrap();
let set = with_permissions(&[String::new()], None).unwrap();
assert_eq!(
serde_json::to_string(&set).unwrap(),
r#"{"permissions":[]}"#
@ -143,11 +187,11 @@ mod tests {
/// A name that is not a permission fails locally and lists the valid ones.
#[test]
fn an_unknown_permission_is_refused() {
let err = with_permissions(&["messaging".to_owned(), "fly".to_owned()]).unwrap_err();
let err = with_permissions(&["messaging".to_owned(), "fly".to_owned()], None).unwrap_err();
let text = err.to_string();
assert!(text.contains("invalid permission \"fly\""), "{text}");
assert!(text.contains("manage_root_agent"), "{text}");
let ok = with_permissions(&["web_tools".to_owned()]).unwrap();
let ok = with_permissions(&["web_tools".to_owned()], None).unwrap();
assert_eq!(
serde_json::to_string(&ok).unwrap(),
r#"{"permissions":["web_tools"]}"#