im pretty sure every subcommands use the config file
This commit is contained in:
+19
-1
@@ -14,6 +14,10 @@ pub struct Cli {
|
|||||||
#[arg(short = 'v', long = "verbose", action = ArgAction::Count, global = true)]
|
#[arg(short = 'v', long = "verbose", action = ArgAction::Count, global = true)]
|
||||||
pub verbose: u8,
|
pub verbose: u8,
|
||||||
|
|
||||||
|
/// Path to the agent config file for commands that use agent config.
|
||||||
|
#[arg(long, global = true)]
|
||||||
|
pub config: Option<PathBuf>,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub command: Command,
|
pub command: Command,
|
||||||
}
|
}
|
||||||
@@ -28,6 +32,9 @@ pub enum Command {
|
|||||||
InitConfig(InitConfigArgs),
|
InitConfig(InitConfigArgs),
|
||||||
/// Reload a running agent daemon by sending SIGHUP.
|
/// Reload a running agent daemon by sending SIGHUP.
|
||||||
Reload(ReloadArgs),
|
Reload(ReloadArgs),
|
||||||
|
/// Upload local observations to the control plane once and exit.
|
||||||
|
#[command(visible_alias = "sync")]
|
||||||
|
SyncObservations(SyncObservationsArgs),
|
||||||
/// Pass local hotplug observations through to the wakey CLI.
|
/// Pass local hotplug observations through to the wakey CLI.
|
||||||
Observe(ObserveArgs),
|
Observe(ObserveArgs),
|
||||||
}
|
}
|
||||||
@@ -76,6 +83,10 @@ pub struct InitConfigArgs {
|
|||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub config: Option<PathBuf>,
|
pub config: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Existing agent config to use as a base before applying explicit overrides.
|
||||||
|
#[arg(long)]
|
||||||
|
pub from_config: Option<PathBuf>,
|
||||||
|
|
||||||
/// Print config to stdout.
|
/// Print config to stdout.
|
||||||
#[arg(long, conflicts_with = "config")]
|
#[arg(long, conflicts_with = "config")]
|
||||||
pub stdout: bool,
|
pub stdout: bool,
|
||||||
@@ -104,10 +115,17 @@ pub struct ReloadArgs {
|
|||||||
pub pid_file: PathBuf,
|
pub pid_file: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Args)]
|
||||||
|
pub struct SyncObservationsArgs {
|
||||||
|
/// Path to the agent config file.
|
||||||
|
#[arg(long, default_value = config::DEFAULT_CONFIG_PATH)]
|
||||||
|
pub config: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
pub struct ObserveArgs {
|
pub struct ObserveArgs {
|
||||||
/// Path to the agent config file. If present, local path settings are passed through.
|
/// Path to the agent config file. If present, local path settings are passed through.
|
||||||
#[arg(long, default_value = config::DEFAULT_CONFIG_PATH)]
|
#[arg(long, global = true, default_value = config::DEFAULT_CONFIG_PATH)]
|
||||||
pub config: PathBuf,
|
pub config: PathBuf,
|
||||||
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
|
|||||||
+57
-20
@@ -15,13 +15,20 @@ use cli::{Cli, Command, InitConfigArgs, ObserveCommand};
|
|||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
tracing::init(cli.verbose);
|
tracing::init(cli.verbose);
|
||||||
|
let global_config = cli.config.as_deref();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Command::Serve(args) => {
|
Command::Serve(mut args) => {
|
||||||
|
if let Some(config) = global_config {
|
||||||
|
args.config = config.to_path_buf();
|
||||||
|
}
|
||||||
::tracing::info!("wakey-agent command: serve");
|
::tracing::info!("wakey-agent command: serve");
|
||||||
serve::serve(args).await?
|
serve::serve(args).await?
|
||||||
}
|
}
|
||||||
Command::Enroll(args) => {
|
Command::Enroll(mut args) => {
|
||||||
|
if let Some(config) = global_config {
|
||||||
|
args.config = config.to_path_buf();
|
||||||
|
}
|
||||||
let resolved_server_url = if let Some(server_url) = args.server_url.as_deref() {
|
let resolved_server_url = if let Some(server_url) = args.server_url.as_deref() {
|
||||||
server_url.to_string()
|
server_url.to_string()
|
||||||
} else {
|
} else {
|
||||||
@@ -81,12 +88,34 @@ async fn main() -> Result<()> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Command::InitConfig(args) => init_config(args)?,
|
Command::InitConfig(mut args) => {
|
||||||
|
if let Some(config) = global_config
|
||||||
|
&& args.config.is_none()
|
||||||
|
&& !args.stdout
|
||||||
|
{
|
||||||
|
args.config = Some(config.to_path_buf());
|
||||||
|
}
|
||||||
|
init_config(args)?
|
||||||
|
}
|
||||||
Command::Reload(args) => {
|
Command::Reload(args) => {
|
||||||
::tracing::info!(pid_file = %args.pid_file.display(), "wakey-agent command: reload");
|
::tracing::info!(pid_file = %args.pid_file.display(), "wakey-agent command: reload");
|
||||||
serve::reload_daemon(&args.pid_file)?
|
serve::reload_daemon(&args.pid_file)?
|
||||||
}
|
}
|
||||||
Command::Observe(args) => observe(args)?,
|
Command::SyncObservations(mut args) => {
|
||||||
|
if let Some(config) = global_config {
|
||||||
|
args.config = config.to_path_buf();
|
||||||
|
}
|
||||||
|
::tracing::info!(config = %args.config.display(), "wakey-agent command: sync-observations");
|
||||||
|
let cfg = config::load_config(&args.config)?;
|
||||||
|
let accepted = session::sync_observations_once(&cfg).await?;
|
||||||
|
println!("observations_synced={accepted}");
|
||||||
|
}
|
||||||
|
Command::Observe(mut args) => {
|
||||||
|
if let Some(config) = global_config {
|
||||||
|
args.config = config.to_path_buf();
|
||||||
|
}
|
||||||
|
observe(args)?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -164,24 +193,32 @@ fn init_config(args: InitConfigArgs) -> Result<()> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg = config::AgentConfig {
|
let mut cfg = if let Some(from_config) = &args.from_config {
|
||||||
server_url: args
|
config::load_config(from_config)?
|
||||||
.server_url
|
} else {
|
||||||
.unwrap_or_else(|| "https://wakey.ldlda.com".to_string()),
|
config::AgentConfig {
|
||||||
agent_id: args
|
server_url: "https://wakey.ldlda.com".to_string(),
|
||||||
.agent_id
|
agent_id: "REPLACE_ME_AGENT_ID".to_string(),
|
||||||
.unwrap_or_else(|| "REPLACE_ME_AGENT_ID".to_string()),
|
agent_token: "REPLACE_ME_AGENT_TOKEN".to_string(),
|
||||||
agent_token: args
|
reconnect_base_ms: 1_000,
|
||||||
.agent_token
|
reconnect_max_ms: 30_000,
|
||||||
.unwrap_or_else(|| "REPLACE_ME_AGENT_TOKEN".to_string()),
|
observation_sync_interval_seconds: 60,
|
||||||
reconnect_base_ms: 1_000,
|
dhcp_leases_path: "/tmp/dhcp.leases".into(),
|
||||||
reconnect_max_ms: 30_000,
|
mac_name_cache_path: "/tmp/wakey_mac_names.json".into(),
|
||||||
observation_sync_interval_seconds: 60,
|
observation_store_path: "/tmp/wakey_observations.json".into(),
|
||||||
dhcp_leases_path: "/tmp/dhcp.leases".into(),
|
}
|
||||||
mac_name_cache_path: "/tmp/wakey_mac_names.json".into(),
|
|
||||||
observation_store_path: "/tmp/wakey_observations.json".into(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(server_url) = args.server_url {
|
||||||
|
cfg.server_url = server_url;
|
||||||
|
}
|
||||||
|
if let Some(agent_id) = args.agent_id {
|
||||||
|
cfg.agent_id = agent_id;
|
||||||
|
}
|
||||||
|
if let Some(agent_token) = args.agent_token {
|
||||||
|
cfg.agent_token = agent_token;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(path) = &args.config {
|
if let Some(path) = &args.config {
|
||||||
config::save_config(path, &cfg)?;
|
config::save_config(path, &cfg)?;
|
||||||
println!("config={}", path.display());
|
println!("config={}", path.display());
|
||||||
|
|||||||
@@ -164,13 +164,18 @@ struct AgentObservationRequest {
|
|||||||
last_seen_unix: u64,
|
last_seen_unix: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_agent_observations(client: &reqwest::Client, config: &AgentConfig) -> Result<()> {
|
pub async fn sync_observations_once(config: &AgentConfig) -> Result<usize> {
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
send_agent_observations(&client, config).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_agent_observations(client: &reqwest::Client, config: &AgentConfig) -> Result<usize> {
|
||||||
let observations =
|
let observations =
|
||||||
wakey::wakey_linux::dhcp::list_local_observations_from_path(&config.observation_store_path)
|
wakey::wakey_linux::dhcp::list_local_observations_from_path(&config.observation_store_path)
|
||||||
.await
|
.await
|
||||||
.context("failed to read local observations")?;
|
.context("failed to read local observations")?;
|
||||||
if observations.is_empty() {
|
if observations.is_empty() {
|
||||||
return Ok(());
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = observations_url(&config.server_url)?;
|
let url = observations_url(&config.server_url)?;
|
||||||
@@ -210,7 +215,7 @@ async fn send_agent_observations(client: &reqwest::Client, config: &AgentConfig)
|
|||||||
observations = payload.observations.len(),
|
observations = payload.observations.len(),
|
||||||
"synced local observations"
|
"synced local observations"
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(payload.observations.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_backoff_ms(current_ms: u64, max_ms: u64) -> u64 {
|
pub fn next_backoff_ms(current_ms: u64, max_ms: u64) -> u64 {
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ pub async fn observe_dhcp_event(
|
|||||||
hostname: Option<&str>,
|
hostname: Option<&str>,
|
||||||
) -> io::Result<bool> {
|
) -> io::Result<bool> {
|
||||||
if !matches!(action, "add" | "update" | "old" | "remove") {
|
if !matches!(action, "add" | "update" | "old" | "remove") {
|
||||||
|
// old not emitted by hotplug
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,6 +229,7 @@ pub async fn observe_neighbor_event(
|
|||||||
ip: Option<IpAddr>,
|
ip: Option<IpAddr>,
|
||||||
) -> io::Result<bool> {
|
) -> io::Result<bool> {
|
||||||
if !matches!(action, "add" | "update" | "old" | "remove") {
|
if !matches!(action, "add" | "update" | "old" | "remove") {
|
||||||
|
// update and remove not emitted by hotplug
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
let Some(key) = mac
|
let Some(key) = mac
|
||||||
|
|||||||
Reference in New Issue
Block a user