Refactor the long-term stats module into cleaner code.

This commit is contained in:
Herbert Wolverson 2023-05-01 13:34:52 +00:00
parent ac304b436b
commit 5a85406e30
4 changed files with 194 additions and 173 deletions

View File

@ -0,0 +1,74 @@
//! Data-types used for license key exchange and lookup.
use serde::{Serialize, Deserialize};
use dryoc::dryocbox::PublicKey;
use thiserror::Error;
/// Network-transmitted query to ask the status of a license
/// key.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum LicenseRequest {
/// Check the validity of a key
LicenseCheck {
/// The Key to Check
key: String,
},
/// Exchange Keys
KeyExchange {
/// The node ID of the requesting shaper node
node_id: String,
/// The pretty name of the requesting shaper node
node_name: String,
/// The license key of the requesting shaper node
license_key: String,
/// The sodium-style public key of the requesting shaper node
public_key: PublicKey,
},
}
/// License server responses for a key
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum LicenseReply {
/// The license is denied
Denied,
/// The license is valid
Valid {
/// When does the license expire?
expiry: u64,
/// Address to which statistics should be submitted
stats_host: String,
},
/// Key Exchange
MyPublicKey {
/// The server's public key
public_key: PublicKey,
},
}
/// Errors that can occur when checking licenses
#[derive(Debug, Error)]
pub enum LicenseCheckError {
/// Serialization error
#[error("Unable to serialize license check")]
SerializeFail,
/// Network error
#[error("Unable to send license check")]
SendFail,
/// Network error
#[error("Unable to receive license result")]
ReceiveFail,
/// Deserialization error
#[error("Unable to deserialize license result")]
DeserializeFail,
}
/// Stores a license id and node id for transport
#[derive(Debug, Serialize, Deserialize)]
pub struct NodeIdAndLicense {
/// The node id
pub node_id: String,
/// The license key
pub license_key: String,
/// The Sodium Nonce
pub nonce: [u8; 24],
}

View File

@ -1,176 +1,8 @@
//! Functions for talking to the license server
use super::{LicenseCheckError, LicenseRequest, LicenseReply, LICENSE_SERVER};
use dryoc::dryocbox::PublicKey;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
/// Type that provides a minimum, maximum and average value
/// for a given statistic within the associated time period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsSummary {
/// Minimum value
pub min: (u64, u64),
/// Maximum value
pub max: (u64, u64),
/// Average value
pub avg: (u64, u64),
}
/// Type that provides a minimum, maximum and average value
/// for a given RTT value within the associated time period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsRttSummary {
/// Minimum value
pub min: u32,
/// Maximum value
pub max: u32,
/// Average value
pub avg: u32,
}
/// Type that holds total traffic statistics for a given time period
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsTotals {
/// Total number of packets
pub packets: StatsSummary,
/// Total number of bits
pub bits: StatsSummary,
/// Total number of shaped bits
pub shaped_bits: StatsSummary,
}
/// Type that holds per-host statistics for a given stats collation
/// period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsHost {
/// Host circuit_id as it appears in ShapedDevices.csv
pub circuit_id: String,
/// Device id as it appears in ShapedDevices.csv
pub device_id: String,
/// Parent node (hopefully in network.json!)
pub parent_node: String,
/// Device name as it appears in ShapedDevices.csv
pub device_name: String,
/// Circuit name as it appears in ShapedDevices.csv
pub circuit_name: String,
/// Host's IP address
pub ip_address: String,
/// Host's MAC address
pub mac: String,
/// Host's traffic statistics
pub bits: StatsSummary,
/// Host's RTT statistics
pub rtt: StatsRttSummary,
/// Positional arguments indicating which tree entries apply
pub tree_indices: Vec<usize>,
}
/// Node inside a traffic summary tree
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsTreeNode {
/// Name (from network.json)
pub name: String,
/// Maximum allowed throughput (from network.json)
pub max_throughput: (u32, u32),
/// Current throughput (from network.json)
pub current_throughput: (u32, u32),
/// RTT summaries
pub rtt: (u16, u16, u16),
/// Indices of parents in the tree
pub parents: Vec<usize>,
/// Index of immediate parent in the tree
pub immediate_parent: Option<usize>,
/// Node Type
pub node_type: Option<String>,
}
/// Collation of all stats for a given time period
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsSubmission {
/// Timestamp of the collation (UNIX time)
pub timestamp: u64,
/// Total traffic statistics
pub totals: Option<StatsTotals>,
/// Per-host statistics
pub hosts: Option<Vec<StatsHost>>,
/// Tree of traffic summaries
pub tree: Option<Vec<StatsTreeNode>>,
/// CPU utiliation on the shaper
pub cpu_usage: Vec<u32>,
/// RAM utilization on the shaper
pub ram_percent: u32,
}
/// Network-transmitted query to ask the status of a license
/// key.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum LicenseRequest {
/// Check the validity of a key
LicenseCheck {
/// The Key to Check
key: String,
},
/// Exchange Keys
KeyExchange {
/// The node ID of the requesting shaper node
node_id: String,
/// The pretty name of the requesting shaper node
node_name: String,
/// The license key of the requesting shaper node
license_key: String,
/// The sodium-style public key of the requesting shaper node
public_key: PublicKey,
},
}
/// License server responses for a key
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum LicenseReply {
/// The license is denied
Denied,
/// The license is valid
Valid {
/// When does the license expire?
expiry: u64,
/// Address to which statistics should be submitted
stats_host: String,
},
/// Key Exchange
MyPublicKey {
/// The server's public key
public_key: PublicKey,
},
}
/// Errors that can occur when checking licenses
#[derive(Debug, Error)]
pub enum LicenseCheckError {
/// Serialization error
#[error("Unable to serialize license check")]
SerializeFail,
/// Network error
#[error("Unable to send license check")]
SendFail,
/// Network error
#[error("Unable to receive license result")]
ReceiveFail,
/// Deserialization error
#[error("Unable to deserialize license result")]
DeserializeFail,
}
/// Stores a license id and node id for transport
#[derive(Debug, Serialize, Deserialize)]
pub struct NodeIdAndLicense {
/// The node id
pub node_id: String,
/// The license key
pub license_key: String,
/// The Sodium Nonce
pub nonce: [u8; 24],
}
use tokio::{net::TcpStream, io::{AsyncReadExt, AsyncWriteExt}};
fn build_license_request(key: String) -> Result<Vec<u8>, LicenseCheckError> {
let mut result = Vec::new();
@ -222,7 +54,6 @@ fn build_key_exchange_request(
Ok(result)
}
const LICENSE_SERVER: &str = "license.libreqos.io:9126";
/// Ask the license server if the license is valid
///

View File

@ -0,0 +1,15 @@
//! Holds data-types and utility functions for the long-term
//! statistics retention system.
//!
//! This is in the bus so that it can be readily shared between
//! server and client code.
mod submissions;
mod license_types;
mod license_utils;
pub use submissions::*;
pub use license_types::*;
pub use license_utils::*;
pub(crate) const LICENSE_SERVER: &str = "license.libreqos.io:9126";

View File

@ -0,0 +1,101 @@
//! Holds data-types to be submitted as part of long-term stats
//! collection.
use serde::{Serialize, Deserialize};
/// Type that provides a minimum, maximum and average value
/// for a given statistic within the associated time period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsSummary {
/// Minimum value
pub min: (u64, u64),
/// Maximum value
pub max: (u64, u64),
/// Average value
pub avg: (u64, u64),
}
/// Type that provides a minimum, maximum and average value
/// for a given RTT value within the associated time period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsRttSummary {
/// Minimum value
pub min: u32,
/// Maximum value
pub max: u32,
/// Average value
pub avg: u32,
}
/// Type that holds total traffic statistics for a given time period
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsTotals {
/// Total number of packets
pub packets: StatsSummary,
/// Total number of bits
pub bits: StatsSummary,
/// Total number of shaped bits
pub shaped_bits: StatsSummary,
}
/// Type that holds per-host statistics for a given stats collation
/// period.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsHost {
/// Host circuit_id as it appears in ShapedDevices.csv
pub circuit_id: String,
/// Device id as it appears in ShapedDevices.csv
pub device_id: String,
/// Parent node (hopefully in network.json!)
pub parent_node: String,
/// Device name as it appears in ShapedDevices.csv
pub device_name: String,
/// Circuit name as it appears in ShapedDevices.csv
pub circuit_name: String,
/// Host's IP address
pub ip_address: String,
/// Host's MAC address
pub mac: String,
/// Host's traffic statistics
pub bits: StatsSummary,
/// Host's RTT statistics
pub rtt: StatsRttSummary,
/// Positional arguments indicating which tree entries apply
pub tree_indices: Vec<usize>,
}
/// Node inside a traffic summary tree
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsTreeNode {
/// Name (from network.json)
pub name: String,
/// Maximum allowed throughput (from network.json)
pub max_throughput: (u32, u32),
/// Current throughput (from network.json)
pub current_throughput: (u32, u32),
/// RTT summaries
pub rtt: (u16, u16, u16),
/// Indices of parents in the tree
pub parents: Vec<usize>,
/// Index of immediate parent in the tree
pub immediate_parent: Option<usize>,
/// Node Type
pub node_type: Option<String>,
}
/// Collation of all stats for a given time period
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct StatsSubmission {
/// Timestamp of the collation (UNIX time)
pub timestamp: u64,
/// Total traffic statistics
pub totals: Option<StatsTotals>,
/// Per-host statistics
pub hosts: Option<Vec<StatsHost>>,
/// Tree of traffic summaries
pub tree: Option<Vec<StatsTreeNode>>,
/// CPU utiliation on the shaper
pub cpu_usage: Vec<u32>,
/// RAM utilization on the shaper
pub ram_percent: u32,
}