Skip to content

Commit

Permalink
Merge pull request #48 from tinythings/isbm-add-relations
Browse files Browse the repository at this point in the history
Fix relations mapping
  • Loading branch information
isbm authored Nov 29, 2024
2 parents 16d86cf + 19e11f6 commit ace7bcf
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
8 changes: 6 additions & 2 deletions examples/models/router/relations/basic.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ relations:
requires:
- no-ssh-sockets

interfaces:
requires:
- addresses
- routes

# State
$:
consists:
requires:
- routes
- interfaces
- addresses
- ssh-sockets
25 changes: 22 additions & 3 deletions libsysinspect/src/intp/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
};
use colored::Colorize;
use serde_yaml::Value;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

pub struct SysInspector {
entities: HashMap<String, Entity>,
Expand Down Expand Up @@ -126,19 +126,29 @@ impl SysInspector {
let mut out: Vec<Action> = Vec::default();
for s in &self.checkbook {
if rids.contains(&s.id()) {
for rel in s.relations() {
out.extend(self.actions_by_entities(rel.get_entities(state.to_owned()), state.to_owned())?);
for r in s.relations() {
out.extend(self.actions_by_entities(r.required(&parse_state(state.clone()))?, state.clone())?);
}
}
}

if out.is_empty() {
return Err(SysinspectError::ModelDSLError(format!(
"Checkbook contains no such relations as \"{}\" that would be aligned with the state \"{}\"",
rids.join(", "),
parse_state(state)
)));
}

Ok(out)
}

/// Get actions by entities
pub fn actions_by_entities(&self, eids: Vec<String>, state: Option<String>) -> Result<Vec<Action>, SysinspectError> {
let mut out: Vec<Action> = Vec::default();
let state = parse_state(state);
let mut dropped: HashSet<String> = HashSet::default();
dropped.extend(eids.clone());

for eid in eids {
for action in self.actions.values() {
Expand All @@ -149,10 +159,19 @@ impl SysInspector {
// it also corresponds to other claims and conditions, and that then
// needs to be passed to the reactor.
out.push(action.to_owned().setup(self, &eid, state.to_owned())?);
dropped.remove(&eid);
}
}
}

if !dropped.is_empty() {
return Err(SysinspectError::ModelDSLError(format!(
"Entities \"{}\" are not bound with the state \"{}\" or don't exist",
dropped.iter().map(|s| s.to_string()).collect::<Vec<String>>().join(", "),
state
)));
}

Ok(out)
}

Expand Down
22 changes: 14 additions & 8 deletions libsysinspect/src/intp/relations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ impl Relation {
&self.states
}

/// Get related entities
pub fn get_entities(&self, state: Option<String>) -> Vec<String> {
let mut out: Vec<String> = Vec::default();
let state = state.unwrap_or_default();
for (st, ent) in self.states() {
if st.eq(&state) || st.eq("$") {
out.extend(ent.values().flat_map(|eids| eids.to_owned()).collect::<Vec<String>>());
/// Get required entities (consists of).
/// There is no clear distinction between "consists of" and "required".
pub fn required(&self, state: &str) -> Result<Vec<String>, SysinspectError> {
let mut out = Vec::default();
if let Some(set) = self.states().get(state) {
if let Some(required) = set.get("requires") {
out.extend(required.iter().map(|s| s.to_string()));
}
} else {
return Err(SysinspectError::ModelDSLError(format!(
"No required entities has been found in the \"{}\" relation as the \"{state}\" state",
self.id()
)));
}
out

Ok(out)
}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use libsysinspect::{
inspector::SysInspectRunner,
logger,
reactor::handlers,
traits::get_minion_traits,
SysinspectError,
};
use log::LevelFilter;
Expand Down Expand Up @@ -108,6 +109,7 @@ fn main() {
sr.set_state(params.get_one::<String>("state").cloned());
sr.set_entities(clidef::split_by(&params, "entities", None));
sr.set_checkbook_labels(clidef::split_by(&params, "labels", None));
sr.set_traits(get_minion_traits(None));
sr.start();
}
}

0 comments on commit ace7bcf

Please sign in to comment.