From 799930ea556bc142005d6b96be9f2849af98cf6c Mon Sep 17 00:00:00 2001 From: "Alexander V. Nikolaev" Date: Fri, 15 Nov 2024 02:15:04 +0200 Subject: [PATCH] Keep vm/agent names in registry Signed-off-by: Alexander V. Nikolaev --- src/admin/entry.rs | 48 +++++++++++++++++++++++++++++++++---------- src/admin/registry.rs | 19 ++++++++++++----- src/admin/server.rs | 10 ++++++--- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/admin/entry.rs b/src/admin/entry.rs index 8cf8c68..3ba32f2 100644 --- a/src/admin/entry.rs +++ b/src/admin/entry.rs @@ -10,10 +10,13 @@ use givc_common::types::*; #[derive(Debug, Clone, PartialEq)] pub enum Placement { // Service is a `givc-agent` and could be directly connected - Endpoint(EndpointEntry), + Endpoint { endpoint: EndpointEntry, vm: String }, // Service or application managed by specified agent - Managed(String), + Managed { vm: String, by: String }, + + // Running on host + Host, } #[derive(Debug, Clone, PartialEq)] @@ -26,14 +29,31 @@ pub struct RegistryEntry { } impl RegistryEntry { + pub fn agent_name(&self) -> Option<&str> { + match &self.placement { + Placement::Endpoint { .. } => Some(&self.name), + Placement::Managed { by, .. } => Some(by), + Placement::Host => None, + } + } + + pub fn vm_name(&self) -> Option<&str> { + match &self.placement { + Placement::Endpoint { vm, .. } => Some(vm), + Placement::Managed { vm, .. } => Some(vm), + Placement::Host => None, + } + } + pub fn agent(&self) -> anyhow::Result<&EndpointEntry> { match &self.placement { - Placement::Endpoint(endpoint) => Ok(endpoint), - Placement::Managed(by) => Err(anyhow!( + Placement::Endpoint { endpoint, .. } => Ok(endpoint), + Placement::Managed { by, .. } => Err(anyhow!( "Agent endpoint {} is managed by {}!", self.name, by )), + Placement::Host => Err(anyhow!("Its a host!")), } } } @@ -57,13 +77,16 @@ impl RegistryEntry { path: "bogus".to_string(), freezer_state: "bogus".to_string(), }, - placement: Placement::Endpoint(EndpointEntry { - address: EndpointAddress::Tcp { - addr: "127.0.0.1".to_string(), - port: 42, + placement: Placement::Endpoint { + endpoint: EndpointEntry { + address: EndpointAddress::Tcp { + addr: "127.0.0.1".to_string(), + port: 42, + }, + tls_name: "bogus".to_string(), }, - tls_name: "bogus".to_string(), - }), + vm: "bogus".into(), + }, watch: true, } } @@ -89,7 +112,10 @@ impl TryFrom for RegistryEntry { status, watch, r#type: ty, - placement: Placement::Endpoint(endpoint), + placement: Placement::Endpoint { + endpoint, + vm: "bogus".into(), + }, }) } } diff --git a/src/admin/registry.rs b/src/admin/registry.rs index ca640ff..1bfdb9b 100644 --- a/src/admin/registry.rs +++ b/src/admin/registry.rs @@ -50,9 +50,12 @@ impl Registry { Some(entry) => { let cascade: Vec = state .values() - .filter_map(|re| match &re.placement { - Placement::Managed(within) if within == name => Some(re.name.clone()), - _ => None, + .filter_map(|re| { + if re.agent_name() == Some(name) || re.vm_name() == Some(name) { + Some(re.name.clone()) + } else { + None + } }) .collect(); for each in cascade { @@ -204,11 +207,17 @@ mod tests { let r = Registry::new(); let foo = RegistryEntry::dummy("foo".to_string()); let bar = RegistryEntry { - placement: Placement::Managed("foo".into()), + placement: Placement::Managed { + by: "foo".into(), + vm: "foo-vm".into(), + }, ..RegistryEntry::dummy("bar".to_string()) }; let baz = RegistryEntry { - placement: Placement::Managed("foo".into()), + placement: Placement::Managed { + by: "foo".into(), + vm: "foo-vm".into(), + }, ..RegistryEntry::dummy("baz".to_string()) }; diff --git a/src/admin/server.rs b/src/admin/server.rs index a132ce4..a25a2dc 100644 --- a/src/admin/server.rs +++ b/src/admin/server.rs @@ -109,14 +109,15 @@ impl AdminServiceImpl { pub fn endpoint(&self, entry: &RegistryEntry) -> anyhow::Result { let transport = match &entry.placement { - Placement::Managed(parent) => { + Placement::Managed { by: parent, .. } => { let parent = self.registry.by_name(parent)?; parent .agent() .with_context(|| "When get_remote_status()")? .to_owned() // Fail, if parent also `Managed` } - Placement::Endpoint(endpoint) => endpoint.clone(), // FIXME: avoid clone! + Placement::Endpoint { endpoint, .. } => endpoint.clone(), // FIXME: avoid clone! + Placement::Host => bail!("endpoint() called for Host"), // impossible, FIXME: should never happens atm }; let tls_name = transport.tls_name.clone(); Ok(EndpointConfig { @@ -332,7 +333,10 @@ impl AdminServiceImpl { vm: VmType::AppVM, service: ServiceType::App, }, - placement: Placement::Managed(systemd_agent), + placement: Placement::Managed { + by: systemd_agent, + vm: vm_name, + }, }; self.registry.register(app_entry); Ok(())