mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Add a new "licman" command.
This is intended to manage the license management server, once it is running. It starts with a command "licman add host <ip>" that adds a data-collector to the available stats hosts pool.
This commit is contained in:
parent
dca44f294a
commit
07dc9c0745
12
src/rust/Cargo.lock
generated
12
src/rust/Cargo.lock
generated
@ -1820,6 +1820,18 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "licman"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.2.1",
|
||||
"env_logger",
|
||||
"log",
|
||||
"pgdb",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
|
@ -30,5 +30,6 @@ members = [
|
||||
"long_term_stats/license_server", # Licensing Server for LibreQoS Long-term stats
|
||||
"long_term_stats/lts_node", # Long-term stats cluster node
|
||||
"long_term_stats/pgdb", # PostgreSQL interface for the LTS system
|
||||
"long_term_stats/licman", # A CLI tool for managing the licensing server
|
||||
"lqos_map_perf", # A CLI tool for testing eBPF map performance
|
||||
]
|
||||
|
@ -20,4 +20,4 @@ stop you.
|
||||
* Setup `/etc/lqdb`.
|
||||
* Copy `lts_keys.bin` from the license server to the `lts_node` directory.
|
||||
* Run the process.
|
||||
* Add the node to the license server.
|
||||
* Login to the licensing server, and run `licman host add <ip of the new host>`
|
||||
|
12
src/rust/long_term_stats/licman/Cargo.toml
Normal file
12
src/rust/long_term_stats/licman/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "licman"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
anyhow = "1"
|
||||
pgdb = { path = "../pgdb" }
|
||||
tokio = { version = "1", features = [ "rt", "macros", "net", "io-util", "time" ] }
|
||||
env_logger = "0"
|
||||
log = "0"
|
64
src/rust/long_term_stats/licman/src/main.rs
Normal file
64
src/rust/long_term_stats/licman/src/main.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::process::exit;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command()]
|
||||
struct Args {
|
||||
#[command(subcommand)]
|
||||
command: Option<Commands>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Manage stats hosts
|
||||
Hosts {
|
||||
#[command(subcommand)]
|
||||
command: Option<HostsCommands>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum HostsCommands {
|
||||
Add { hostname: String },
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<()> {
|
||||
env_logger::init_from_env(
|
||||
env_logger::Env::default()
|
||||
.filter_or(env_logger::DEFAULT_FILTER_ENV, "warn"),
|
||||
);
|
||||
|
||||
// Get the database connection pool
|
||||
let pool = pgdb::get_connection_pool(5).await;
|
||||
if pool.is_err() {
|
||||
log::error!("Unable to connect to the database");
|
||||
log::error!("{pool:?}");
|
||||
return Err(anyhow::Error::msg("Unable to connect to the database"));
|
||||
}
|
||||
let pool = pool.unwrap();
|
||||
|
||||
let cli = Args::parse();
|
||||
match cli.command {
|
||||
Some(Commands::Hosts {
|
||||
command: Some(HostsCommands::Add { hostname }),
|
||||
}) => {
|
||||
match pgdb::add_stats_host(pool, hostname).await {
|
||||
Err(e) => {
|
||||
log::error!("Unable to add stats host: {e:?}");
|
||||
exit(1);
|
||||
}
|
||||
Ok(new_id) => {
|
||||
println!("Added stats host with id {}", new_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(Commands::Hosts { command: None }) | None => {
|
||||
println!("Run with --help to see instructions");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
39
src/rust/long_term_stats/pgdb/src/hosts.rs
Normal file
39
src/rust/long_term_stats/pgdb/src/hosts.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use sqlx::{Pool, Postgres, Row};
|
||||
use crate::license::StatsHostError;
|
||||
|
||||
pub async fn add_stats_host(cnn: Pool<Postgres>, hostname: String) -> Result<i64, StatsHostError> {
|
||||
// Does the stats host already exist? We don't want duplicates
|
||||
let row = sqlx::query("SELECT COUNT(*) AS count FROM stats_hosts WHERE ip_address=$1")
|
||||
.bind(&hostname)
|
||||
.fetch_one(&cnn)
|
||||
.await
|
||||
.map_err(|e| StatsHostError::DatabaseError(e.to_string()))?;
|
||||
|
||||
let count: i64 = row.try_get("count").map_err(|e| StatsHostError::DatabaseError(e.to_string()))?;
|
||||
|
||||
if count != 0 {
|
||||
return Err(StatsHostError::HostAlreadyExists);
|
||||
}
|
||||
|
||||
// Get the new primary key
|
||||
log::info!("Getting new primary key for stats host");
|
||||
let row = sqlx::query("SELECT NEXTVAL('stats_hosts_id_seq') AS id")
|
||||
.fetch_one(&cnn)
|
||||
.await
|
||||
.map_err(|e| StatsHostError::DatabaseError(e.to_string()))?;
|
||||
|
||||
|
||||
let new_id: i64 = row.try_get("id").map_err(|e| StatsHostError::DatabaseError(e.to_string()))?;
|
||||
|
||||
// Insert the stats host
|
||||
log::info!("Inserting new stats host: {} ({})", hostname, new_id);
|
||||
sqlx::query("INSERT INTO stats_hosts (id, ip_address, can_accept_new_clients) VALUES ($1, $2, $3)")
|
||||
.bind(new_id)
|
||||
.bind(&hostname)
|
||||
.bind(true)
|
||||
.execute(&cnn)
|
||||
.await
|
||||
.map_err(|e| StatsHostError::DatabaseError(e.to_string()))?;
|
||||
|
||||
Ok(new_id)
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
mod connection;
|
||||
mod license;
|
||||
mod organization;
|
||||
mod hosts;
|
||||
|
||||
pub mod sqlx {
|
||||
pub use sqlx::*;
|
||||
@ -8,4 +9,5 @@ pub mod sqlx {
|
||||
|
||||
pub use connection::get_connection_pool;
|
||||
pub use license::{get_stats_host_for_key, insert_or_update_node_public_key, fetch_public_key};
|
||||
pub use organization::{OrganizationDetails, get_organization};
|
||||
pub use organization::{OrganizationDetails, get_organization};
|
||||
pub use hosts::add_stats_host;
|
@ -72,4 +72,6 @@ pub async fn fetch_public_key(cnn: Pool<Postgres>, license_key: &str, node_id: &
|
||||
pub enum StatsHostError {
|
||||
#[error("Database error occurred")]
|
||||
DatabaseError(String),
|
||||
#[error("Host already exists")]
|
||||
HostAlreadyExists,
|
||||
}
|
Loading…
Reference in New Issue
Block a user