hive-sh4re: split tool-group + capability enums into their own topic module
This commit is contained in:
parent
138f6b6c10
commit
d3ac4de8fb
11 changed files with 313 additions and 296 deletions
|
|
@ -3,7 +3,7 @@
|
|||
//! and `tool-groups.json`.
|
||||
//!
|
||||
//! Format: a JSON object mapping agent name to an array of
|
||||
//! `hive_sh4re::Capability` `snake_case` strings:
|
||||
//! `hive_sh4re::permissions::Capability` `snake_case` strings:
|
||||
//!
|
||||
//! ```json
|
||||
//! {
|
||||
|
|
@ -52,7 +52,7 @@ pub fn caps_for(name: &str) -> Vec<String> {
|
|||
|
||||
/// Check whether an agent holds a specific capability.
|
||||
#[must_use]
|
||||
pub fn has_cap(name: &str, cap: hive_sh4re::Capability) -> bool {
|
||||
pub fn has_cap(name: &str, cap: hive_sh4re::permissions::Capability) -> bool {
|
||||
caps_for(name)
|
||||
.iter()
|
||||
.any(|s| s.eq_ignore_ascii_case(cap.as_str()))
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
//! and the meta `flake.nix`.
|
||||
//!
|
||||
//! Format: a JSON object mapping agent name to an array of
|
||||
//! `hive_sh4re::ToolGroup` `snake_case` strings:
|
||||
//! `hive_sh4re::permissions::ToolGroup` `snake_case` strings:
|
||||
//!
|
||||
//! ```json
|
||||
//! {
|
||||
|
|
@ -70,7 +70,7 @@ fn write(map: &BTreeMap<String, Vec<String>>) -> std::io::Result<()> {
|
|||
/// Returns `Ok(())` when all names are known, or `Err` listing the
|
||||
/// unrecognised names so callers can surface a useful error message.
|
||||
pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
|
||||
let valid: std::collections::BTreeSet<&str> = hive_sh4re::ToolGroup::ALL
|
||||
let valid: std::collections::BTreeSet<&str> = hive_sh4re::permissions::ToolGroup::ALL
|
||||
.iter()
|
||||
.map(|g| g.as_str())
|
||||
.collect();
|
||||
|
|
@ -85,7 +85,7 @@ pub fn validate_groups(groups: &[String]) -> anyhow::Result<()> {
|
|||
anyhow::bail!(
|
||||
"unknown tool group(s): {}; valid names are: {}",
|
||||
unknown.join(", "),
|
||||
hive_sh4re::ToolGroup::ALL
|
||||
hive_sh4re::permissions::ToolGroup::ALL
|
||||
.iter()
|
||||
.map(|g| g.as_str())
|
||||
.collect::<Vec<_>>()
|
||||
|
|
|
|||
|
|
@ -696,7 +696,7 @@ impl Coordinator {
|
|||
/// rebuild-queue worker after a `PermChange` / Capabilities entry
|
||||
/// commits the JSON file, so the P3RM1SS10NS tab updates live.
|
||||
pub fn emit_capabilities_snapshot(self: &Arc<Self>) {
|
||||
use hive_sh4re::Capability;
|
||||
use hive_sh4re::permissions::Capability;
|
||||
let caps = Capability::ALL.iter().map(|c| c.as_str()).collect();
|
||||
let descriptions = Capability::ALL
|
||||
.iter()
|
||||
|
|
@ -723,7 +723,7 @@ impl Coordinator {
|
|||
/// rebuild-queue worker after a `PermChange` / `ToolGroups` entry
|
||||
/// commits the JSON file, so the P3RM1SS10NS tab updates live.
|
||||
pub fn emit_tool_groups_snapshot(self: &Arc<Self>) {
|
||||
use hive_sh4re::ToolGroup;
|
||||
use hive_sh4re::permissions::ToolGroup;
|
||||
let groups = ToolGroup::ALL.iter().map(|g| g.as_str()).collect();
|
||||
let descriptions = ToolGroup::ALL
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ pub(super) struct ToolGroupsSnapshot {
|
|||
pub(super) async fn get_tool_groups(
|
||||
State(state): State<AppState>,
|
||||
) -> axum::Json<ToolGroupsSnapshot> {
|
||||
let groups = hive_sh4re::ToolGroup::ALL
|
||||
let groups = hive_sh4re::permissions::ToolGroup::ALL
|
||||
.iter()
|
||||
.map(|g| g.as_str())
|
||||
.collect();
|
||||
let descriptions = hive_sh4re::ToolGroup::ALL
|
||||
let descriptions = hive_sh4re::permissions::ToolGroup::ALL
|
||||
.iter()
|
||||
.map(|g| (g.as_str(), g.description()))
|
||||
.collect();
|
||||
|
|
@ -80,7 +80,7 @@ pub(super) async fn get_tool_groups(
|
|||
/// the container actually runs with.
|
||||
#[must_use]
|
||||
pub(crate) fn tool_group_default_names() -> Vec<&'static str> {
|
||||
hive_sh4re::ToolGroup::AGENT_DEFAULT
|
||||
hive_sh4re::permissions::ToolGroup::AGENT_DEFAULT
|
||||
.iter()
|
||||
.map(|g| g.as_str())
|
||||
.collect()
|
||||
|
|
@ -204,7 +204,7 @@ pub(super) struct CapabilitiesSnapshot {
|
|||
pub(super) async fn get_capabilities(
|
||||
State(state): State<AppState>,
|
||||
) -> axum::Json<CapabilitiesSnapshot> {
|
||||
use hive_sh4re::Capability;
|
||||
use hive_sh4re::permissions::Capability;
|
||||
let caps = Capability::ALL.iter().map(|c| c.as_str()).collect();
|
||||
let descriptions = Capability::ALL
|
||||
.iter()
|
||||
|
|
@ -256,7 +256,7 @@ pub(super) async fn post_capabilities(
|
|||
if let Some(reject) = guard_agent_name(&state, &logical).await {
|
||||
return Ok(reject);
|
||||
}
|
||||
let known: Vec<&str> = hive_sh4re::Capability::ALL
|
||||
let known: Vec<&str> = hive_sh4re::permissions::Capability::ALL
|
||||
.iter()
|
||||
.map(|c| c.as_str())
|
||||
.collect();
|
||||
|
|
@ -334,7 +334,7 @@ pub(super) async fn post_permissions(
|
|||
State(state): State<AppState>,
|
||||
axum::Json(body): axum::Json<BatchPermsBody>,
|
||||
) -> Result<Response, ProblemDetails> {
|
||||
let known_caps: Vec<&str> = hive_sh4re::Capability::ALL
|
||||
let known_caps: Vec<&str> = hive_sh4re::permissions::Capability::ALL
|
||||
.iter()
|
||||
.map(|c| c.as_str())
|
||||
.collect();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ async fn handle_restart_infra(
|
|||
coord.emit_audit_entry(entry);
|
||||
}
|
||||
};
|
||||
if !crate::capabilities::has_cap(agent, hive_sh4re::Capability::InfraAdmin) {
|
||||
if !crate::capabilities::has_cap(agent, hive_sh4re::permissions::Capability::InfraAdmin) {
|
||||
tracing::warn!(%agent, %name, "agent: infra restart denied (no infra_admin capability)");
|
||||
audit(
|
||||
crate::audit_log::AuditOutcome::Err,
|
||||
|
|
|
|||
|
|
@ -757,7 +757,10 @@ fn require_new_child(agent: &str, target: &str, action: &str) -> Option<Response
|
|||
/// gated on `QueryAgentState`.
|
||||
fn handle_get_loose_ends(coord: &Arc<Coordinator>, agent: &str, target: Option<&str>) -> Response {
|
||||
let result = if target == Some("*") {
|
||||
if !crate::capabilities::has_cap(agent, hive_sh4re::Capability::QueryAgentState) {
|
||||
if !crate::capabilities::has_cap(
|
||||
agent,
|
||||
hive_sh4re::permissions::Capability::QueryAgentState,
|
||||
) {
|
||||
return Response::Err {
|
||||
message: "query_agent_state capability required for hive-wide loose ends"
|
||||
.to_owned(),
|
||||
|
|
@ -801,7 +804,10 @@ fn resolve_agent_state_target<'a>(
|
|||
if crate::topology::is_descendant_of(name, caller) {
|
||||
return Ok(name);
|
||||
}
|
||||
if crate::capabilities::has_cap(caller, hive_sh4re::Capability::QueryAgentState) {
|
||||
if crate::capabilities::has_cap(
|
||||
caller,
|
||||
hive_sh4re::permissions::Capability::QueryAgentState,
|
||||
) {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(format!(
|
||||
|
|
@ -842,7 +848,7 @@ pub async fn dispatch_host_journal(agent: &str, args: HostJournalArgs<'_>) -> Re
|
|||
since,
|
||||
until,
|
||||
} = args;
|
||||
if !crate::capabilities::has_cap(agent, hive_sh4re::Capability::ReadHostJournal) {
|
||||
if !crate::capabilities::has_cap(agent, hive_sh4re::permissions::Capability::ReadHostJournal) {
|
||||
return Response::Err {
|
||||
message: "agent does not have the read_host_journal capability".to_owned(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ fn seed_manager_tool_groups() {
|
|||
tracing::debug!("manager tool groups already set — leaving as-is");
|
||||
return;
|
||||
}
|
||||
let all_groups: Vec<String> = hive_sh4re::ToolGroup::MANAGER_DEFAULT
|
||||
let all_groups: Vec<String> = hive_sh4re::permissions::ToolGroup::MANAGER_DEFAULT
|
||||
.iter()
|
||||
.map(|g| g.as_str().to_owned())
|
||||
.collect();
|
||||
|
|
|
|||
Loading…
Reference in a new issue