netdox_plugin_rs/
get.rs

1use redis::{self, cmd, AsyncCommands};
2use std::collections::{HashMap, HashSet};
3
4use crate::{
5    error::{FCallError, FCallResult},
6    model::{NetdoxReader, Node},
7};
8
9const QUALIFY_DNS_NAME_FN: &str = "netdox_qualify_dns_names";
10
11const META_KEY: &str = "meta";
12const DNS_KEY: &str = "dns";
13const NODES_KEY: &str = "nodes";
14const PROC_NODES_KEY: &str = "proc_nodes";
15const DEFAULT_NETWORK_KEY: &str = "default_network";
16
17impl NetdoxReader for redis::aio::MultiplexedConnection {
18    async fn get_default_network(&mut self) -> FCallResult<String> {
19        Ok(self.get(DEFAULT_NETWORK_KEY).await?)
20    }
21
22    async fn qualify_dns_names(&mut self, names: Vec<String>) -> FCallResult<Vec<String>> {
23        Ok(cmd(QUALIFY_DNS_NAME_FN)
24            .arg(names.len() as u32)
25            .arg(&names)
26            .query_async(self)
27            .await?)
28    }
29
30    async fn get_dns_names(&mut self) -> FCallResult<HashSet<String>> {
31        Ok(self.smembers(DNS_KEY).await?)
32    }
33
34    async fn get_nodes(&mut self) -> FCallResult<Vec<Node>> {
35        let mut nodes = Vec::new();
36        let link_ids: Vec<String> = self.smembers(PROC_NODES_KEY).await?;
37        for link_id in link_ids {
38            nodes.push(self.get_node(&link_id).await?);
39        }
40        Ok(nodes)
41    }
42
43    async fn get_node(&mut self, link_id: &str) -> FCallResult<Node> {
44        let name: String = self.get(format!("{PROC_NODES_KEY};{link_id}")).await?;
45        let alt_names: HashSet<String> = self
46            .smembers(format!("{PROC_NODES_KEY};{link_id};alt_names"))
47            .await?;
48        let dns_names: HashSet<String> = self
49            .smembers(format!("{PROC_NODES_KEY};{link_id};dns_names"))
50            .await?;
51        let raw_ids: HashSet<String> = self
52            .smembers(format!("{PROC_NODES_KEY};{link_id};raw_ids"))
53            .await?;
54        let plugins: HashSet<String> = self
55            .smembers(format!("{PROC_NODES_KEY};{link_id};plugins"))
56            .await?;
57
58        Ok(Node {
59            name,
60            link_id: link_id.to_string(),
61            alt_names,
62            dns_names,
63            raw_ids,
64            plugins,
65        })
66    }
67
68    async fn get_dns_metadata(&mut self, name: &str) -> FCallResult<HashMap<String, String>> {
69        let qualified_name = match self
70            .qualify_dns_names(vec![name.to_string()])
71            .await?
72            .into_iter()
73            .next()
74        {
75            Some(qn) => qn,
76            None => {
77                return Err(FCallError::Logic(
78                    "Tried to qualify one DNS name but got zero back.",
79                ))
80            }
81        };
82
83        Ok(self
84            .hgetall(format!("{META_KEY};{DNS_KEY};{qualified_name}"))
85            .await?)
86    }
87
88    async fn get_node_metadata(&mut self, node: &Node) -> FCallResult<HashMap<String, String>> {
89        let mut meta = HashMap::new();
90        for raw_id in &node.raw_ids {
91            let raw_meta: HashMap<String, String> = self
92                .hgetall(format!("{META_KEY};{NODES_KEY};{raw_id}"))
93                .await?;
94            meta.extend(raw_meta);
95        }
96        let proc_meta: HashMap<String, String> = self
97            .hgetall(format!("{META_KEY};{PROC_NODES_KEY};{}", node.link_id))
98            .await?;
99        meta.extend(proc_meta);
100        Ok(meta)
101    }
102}