Add offline resource capability discovery
This commit is contained in:
parent
116a431a12
commit
47d16eb714
6 changed files with 200 additions and 12 deletions
|
|
@ -5,7 +5,7 @@ mod local_control;
|
|||
mod local_transport;
|
||||
mod peer_client;
|
||||
mod peer_control;
|
||||
mod resource_contracts;
|
||||
pub mod resource_contracts;
|
||||
mod runtime;
|
||||
pub mod service;
|
||||
mod sync;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
//! Reviewable resource-family contracts for daemon handlers.
|
||||
//!
|
||||
//! These contracts are intentionally small and static. They make every
|
||||
//! resource family name its resource ID pattern, remote capabilities, and
|
||||
//! resource family name its resource ID pattern, resource-scoped capabilities, and
|
||||
//! mutation or host-access points in one place while the implementation
|
||||
//! continues to live in the focused handler functions in `lib.rs` and
|
||||
//! `local_control.rs`.
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct ResourceModuleContract {
|
||||
pub(crate) family: &'static str,
|
||||
pub(crate) resource_ids: &'static [&'static str],
|
||||
pub(crate) capabilities: &'static [&'static str],
|
||||
pub(crate) mutation_points: &'static [&'static str],
|
||||
pub struct ResourceModuleContract {
|
||||
pub family: &'static str,
|
||||
pub resource_ids: &'static [&'static str],
|
||||
pub capabilities: &'static [&'static str],
|
||||
pub mutation_points: &'static [&'static str],
|
||||
}
|
||||
|
||||
pub(crate) const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
||||
pub const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
||||
ResourceModuleContract {
|
||||
family: "cas-file-root",
|
||||
resource_ids: &["resource:cas:local", "resource:cas-tree:<name>"],
|
||||
|
|
@ -29,7 +29,12 @@ pub(crate) const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
|||
ResourceModuleContract {
|
||||
family: "kv",
|
||||
resource_ids: &["resource:kv:<name>"],
|
||||
capabilities: &["kv.read", "kv.write_prefix:<prefix>", "kv.write_key:<key>"],
|
||||
capabilities: &[
|
||||
"kv.read",
|
||||
"kv.write",
|
||||
"kv.write_prefix:<prefix>",
|
||||
"kv.write_key:<key>",
|
||||
],
|
||||
mutation_points: &[
|
||||
"local SQLite-backed KV create/set",
|
||||
"authorized sync imports newer or equal timestamp entries idempotently",
|
||||
|
|
@ -87,7 +92,14 @@ pub(crate) const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
|||
"resource:ssh-proxy:local",
|
||||
],
|
||||
capabilities: &[
|
||||
"ssh_cert.request",
|
||||
"ssh_cert.read",
|
||||
"ssh_cert.approve",
|
||||
"ssh_cert.import",
|
||||
"ssh_cert.sync",
|
||||
"ssh_revocation.publish",
|
||||
"ssh_revocation.read",
|
||||
"ssh_revocation.import",
|
||||
"ssh_revocation.sync",
|
||||
"ssh_proxy.connect",
|
||||
"ssh_proxy.admin_shell",
|
||||
|
|
@ -102,7 +114,7 @@ pub(crate) const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
|||
ResourceModuleContract {
|
||||
family: "overlay",
|
||||
resource_ids: &["resource:overlay:<name>"],
|
||||
capabilities: &["overlay.route"],
|
||||
capabilities: &["overlay.join", "overlay.route"],
|
||||
mutation_points: &[
|
||||
"local overlay network membership metadata",
|
||||
"daemon-lifetime packet queue and optional TUN/Wintun injection",
|
||||
|
|
@ -111,7 +123,8 @@ pub(crate) const RESOURCE_MODULE_CONTRACTS: &[ResourceModuleContract] = &[
|
|||
},
|
||||
];
|
||||
|
||||
pub(crate) fn contracts() -> &'static [ResourceModuleContract] {
|
||||
#[must_use]
|
||||
pub fn contracts() -> &'static [ResourceModuleContract] {
|
||||
RESOURCE_MODULE_CONTRACTS
|
||||
}
|
||||
|
||||
|
|
@ -160,4 +173,43 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn catalog_includes_operator_facing_grant_vocabulary() {
|
||||
let capabilities = RESOURCE_MODULE_CONTRACTS
|
||||
.iter()
|
||||
.flat_map(|contract| contract.capabilities.iter().copied())
|
||||
.collect::<std::collections::BTreeSet<_>>();
|
||||
|
||||
for expected in [
|
||||
"cas.fetch",
|
||||
"kv.read",
|
||||
"kv.write",
|
||||
"db.sync",
|
||||
"document.read",
|
||||
"pubsub.publish",
|
||||
"pubsub.subscribe",
|
||||
"pipe.connect",
|
||||
"pipe.listen",
|
||||
"pipe.forward",
|
||||
"ssh_cert.request",
|
||||
"ssh_cert.read",
|
||||
"ssh_cert.approve",
|
||||
"ssh_cert.import",
|
||||
"ssh_cert.sync",
|
||||
"ssh_revocation.publish",
|
||||
"ssh_revocation.read",
|
||||
"ssh_revocation.import",
|
||||
"ssh_revocation.sync",
|
||||
"ssh_proxy.connect",
|
||||
"ssh_proxy.admin_shell",
|
||||
"overlay.join",
|
||||
"overlay.route",
|
||||
] {
|
||||
assert!(
|
||||
capabilities.contains(expected),
|
||||
"missing capability {expected}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue