-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
134: add inventory service and clients (sans auth) (#86)
* add add inventory service and clients * update to db field to i64; update db query * impl feedback: persist inventory cache; remove unauthenticated inventory service call; logs
- Loading branch information
Showing
26 changed files
with
746 additions
and
166 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use std::{path::PathBuf, time::Duration}; | ||
use util_libs::nats::{ | ||
jetstream_client::{get_event_listeners, get_nats_url, with_event_listeners, JsClient}, | ||
types::JsClientBuilder, | ||
}; | ||
|
||
const HOST_AGENT_CLIENT_NAME: &str = "Host Agent"; | ||
const HOST_AGENT_INBOX_PREFIX: &str = "_WORKLOAD_INBOX"; | ||
|
||
pub async fn run(host_pubkey: &str, host_creds_path: &Option<PathBuf>) -> anyhow::Result<JsClient> { | ||
let nats_url = get_nats_url(); | ||
log::info!("nats_url : {}", nats_url); | ||
log::info!("host_creds_path : {:?}", host_creds_path); | ||
log::info!("host_pubkey : {}", host_pubkey); | ||
|
||
let pubkey_lowercase: String = host_pubkey.to_string().to_lowercase(); | ||
|
||
let creds = host_creds_path | ||
.as_ref() | ||
.map(|path| path.to_string_lossy().to_string()); | ||
|
||
let host_client = JsClient::new(JsClientBuilder { | ||
nats_url: nats_url.clone(), | ||
name: HOST_AGENT_CLIENT_NAME.to_string(), | ||
inbox_prefix: format!("{}.{}", pubkey_lowercase, HOST_AGENT_INBOX_PREFIX), | ||
credentials_path: creds.clone(), | ||
ping_interval: Some(Duration::from_secs(10)), | ||
request_timeout: Some(Duration::from_secs(29)), | ||
listeners: vec![with_event_listeners(get_event_listeners())], | ||
}) | ||
.await | ||
.map_err(|e| anyhow::anyhow!("connecting to NATS via {nats_url}: {e}"))?; | ||
|
||
Ok(host_client) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
This client is associated with the: | ||
- WORKLOAD account | ||
- host user | ||
This client is responsible for subscribing to workload streams that handle: | ||
- installing new workloads onto the hosting device | ||
- removing workloads from the hosting device | ||
- sending workload status upon request | ||
- sending out active periodic workload reports | ||
*/ | ||
|
||
use anyhow::Result; | ||
use hpos_hal::inventory::HoloInventory; | ||
use inventory::INVENTORY_UPDATE_SUBJECT; | ||
use tokio::time::sleep; | ||
use util_libs::nats::{jetstream_client::JsClient, types::PublishInfo}; | ||
|
||
pub fn should_check_inventory( | ||
start: chrono::DateTime<chrono::Utc>, | ||
check_interval_duration: chrono::TimeDelta, | ||
) -> bool { | ||
let now = chrono::Utc::now(); | ||
now.signed_duration_since(start) > check_interval_duration | ||
} | ||
|
||
pub async fn run( | ||
host_client: JsClient, | ||
host_pubkey: &str, | ||
inventory_file_path: &str, | ||
host_inventory_check_interval_sec: u64, | ||
) -> Result<(), async_nats::Error> { | ||
log::info!("Host Agent Client: starting Inventory job..."); | ||
|
||
// Store latest inventory record in memory | ||
let starting_inventory = HoloInventory::from_host(); | ||
starting_inventory.save_to_file(inventory_file_path)?; | ||
|
||
let one_hour_interval = tokio::time::Duration::from_secs(host_inventory_check_interval_sec); | ||
let check_interval_duration = chrono::TimeDelta::seconds(one_hour_interval.as_secs() as i64); | ||
let mut last_check_time = chrono::Utc::now(); | ||
|
||
let pubkey_lowercase = host_pubkey.to_string().to_lowercase(); | ||
|
||
loop { | ||
// Periodically check inventory and compare against latest state (in-memory) | ||
if should_check_inventory(last_check_time, check_interval_duration) { | ||
log::debug!("Checking Host inventory..."); | ||
|
||
let current_inventory = HoloInventory::from_host(); | ||
if HoloInventory::load_from_file(inventory_file_path)? != current_inventory { | ||
log::debug!("Host Inventory has changed. About to push update to Orchestrator"); | ||
let authenticated_user_inventory_subject = | ||
format!("INVENTORY.{pubkey_lowercase}.{INVENTORY_UPDATE_SUBJECT}"); | ||
|
||
let payload_bytes = serde_json::to_vec(¤t_inventory)?; | ||
|
||
let payload = PublishInfo { | ||
subject: authenticated_user_inventory_subject, | ||
msg_id: chrono::Utc::now().to_string(), | ||
data: payload_bytes, | ||
headers: None, | ||
}; | ||
|
||
host_client.publish(payload).await?; | ||
current_inventory.save_to_file(inventory_file_path)?; | ||
} else { | ||
log::debug!("Host Inventory has not changed."); | ||
} | ||
|
||
last_check_time = chrono::Utc::now(); | ||
} | ||
|
||
sleep(one_hour_interval).await; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
pub mod gen_leaf_server; | ||
pub mod host_client; | ||
pub mod inventory; | ||
pub mod workload; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use std::path::PathBuf; | ||
use std::time::Duration; | ||
use std::vec; | ||
use util_libs::nats::{ | ||
jetstream_client::{get_event_listeners, get_nats_url, with_event_listeners, JsClient}, | ||
types::JsClientBuilder, | ||
}; | ||
|
||
const ORCHESTRATOR_ADMIN_CLIENT_NAME: &str = "Orchestrator Admin Client"; | ||
const ORCHESTRATOR_ADMIN_CLIENT_INBOX_PREFIX: &str = "ORCHESTRATOR._ADMIN_INBOX"; | ||
|
||
pub async fn run(admin_creds_path: &Option<PathBuf>) -> anyhow::Result<JsClient> { | ||
let nats_url = get_nats_url(); | ||
log::info!("nats_url : {}", nats_url); | ||
|
||
let creds = admin_creds_path | ||
.as_ref() | ||
.map(|path| path.to_string_lossy().to_string()); | ||
|
||
let admin_client = JsClient::new(JsClientBuilder { | ||
nats_url: nats_url.clone(), | ||
name: ORCHESTRATOR_ADMIN_CLIENT_NAME.to_string(), | ||
inbox_prefix: ORCHESTRATOR_ADMIN_CLIENT_INBOX_PREFIX.to_string(), | ||
credentials_path: creds.clone(), | ||
request_timeout: Some(Duration::from_secs(29)), | ||
ping_interval: Some(Duration::from_secs(10)), | ||
listeners: vec![with_event_listeners(get_event_listeners())], | ||
}) | ||
.await | ||
.map_err(|e| anyhow::anyhow!("connecting to NATS via {nats_url}: {e}"))?; | ||
|
||
Ok(admin_client) | ||
} |
Oops, something went wrong.