Skip to content

Commit e5d8345

Browse files
committed
add subcommand
1 parent 21f3fe7 commit e5d8345

14 files changed

+830
-81
lines changed

Cargo.lock

+659-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ libc = "0.2"
1919
ctrlc = { version = "3.4", features = ["termination"] }
2020
rustix = "0.38.30"
2121
ipnet = "2.9.0"
22-
lazy_static = "1.4"
22+
lazy_static = "1.4"
23+
config = "0.14.0"
24+
notify = "6.0"
25+
clap = { version = "4.5.8", features = ["derive"] }

src/capture/capture.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::{borrow::Borrow, collections::HashMap, io::Error, sync::Mutex};
1212
use tokio::task;
1313

1414
pub struct Capture {
15-
pub capture_pool: Arc<Mutex<HashMap<String, task::JoinHandle<u32>>>>,
15+
capture_pool: Arc<Mutex<HashMap<String, task::JoinHandle<u32>>>>,
1616
capture_interface_list: Vec<NetworkInterface>,
1717
}
1818

src/capture/interface.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
use pnet::datalink;
2-
use std::sync::Mutex;
32

43
pub struct InterfaceHandler {
5-
interface_list: Mutex<Vec<datalink::NetworkInterface>>,
4+
interface_list: Vec<String>,
65
}
76

87
impl InterfaceHandler {
98
pub fn new() -> Self {
109
Self {
11-
interface_list: Mutex::new(Vec::new()),
10+
interface_list: vec![],
1211
}
1312
}
1413

1514
pub fn listen_interface(&self) {
16-
let listen_interfaces_thread = tokio::spawn(async {
17-
// loop {
18-
// datalink::interfaces()
19-
// }
20-
});
2115
}
2216

2317
pub fn get_interfaces(&self) -> Vec<datalink::NetworkInterface> {
24-
// let guard = self.interface_list.lock().unwrap();
25-
// guard.clone()
26-
datalink::interfaces()
18+
return vec![];
2719
}
2820
}

src/cmd/capture.rs

+32
Original file line numberDiff line numberDiff line change
@@ -1 +1,33 @@
1+
use std::process;
2+
use clap::{command, value_parser, Arg, ArgAction, ArgGroup, ArgMatches, Command};
3+
use tokio::signal;
4+
use crate::capture::capture::Capture;
15

6+
pub fn capture() -> Command {
7+
Command::new("capture")
8+
}
9+
10+
11+
async fn start_capture() {
12+
// here to start handle interfaces and data capture
13+
tokio::spawn(async {
14+
let capture = Capture::new();
15+
match capture.run() {
16+
Ok(_) => {}
17+
Err(e) => {
18+
panic!("{}", e);
19+
}
20+
}
21+
});
22+
23+
24+
match signal::ctrl_c().await {
25+
Ok(()) => {
26+
println!("bye!!!!");
27+
process::exit(0);
28+
}
29+
Err(err) => {
30+
eprintln!("Unable to listen for shutdown signal: {}", err);
31+
}
32+
}
33+
}

src/cmd/config.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use clap::{Arg, Command};
2+
3+
pub fn config() -> Command {
4+
Command::new("config").args(
5+
[
6+
Arg::new("test"),
7+
Arg::new("")
8+
]
9+
)
10+
}

src/cmd/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
mod capture;
2-
mod reload;
3-
mod stop;
1+
pub mod capture;
2+
pub mod reload;
3+
pub mod stop;
4+
pub mod version;
5+
pub mod config;

src/cmd/reload.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
use clap::Command;
12

3+
pub fn reload() -> Command {
4+
Command::new("reload")
5+
}

src/cmd/stop.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use clap::Command;
2+
3+
pub fn stop() -> Command {
4+
Command::new("stop")
5+
}

src/cmd/version.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use clap::Command;
2+
3+
pub fn version() -> Command {
4+
Command::new("version")
5+
}

src/conf/conf.rs

+82-30
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
1-
use lazy_static::lazy_static;
1+
#![allow(deprecated)]
2+
use std::collections::HashMap;
23
use serde_derive::{Deserialize, Serialize};
3-
use std::fs::File;
4-
use std::io::Read;
4+
use config::{Config, File};
5+
use notify::{Event, RecommendedWatcher, RecursiveMode, Watcher};
6+
use std::path::Path;
7+
use std::sync::mpsc::channel;
8+
use std::sync::RwLock;
9+
use std::thread;
10+
use std::time::Duration;
11+
12+
const CONFIG_PATH :&str = "src/config.toml";
513

614
#[derive(Serialize, Deserialize, Debug)]
7-
pub struct Config {
8-
pub net: NetConfig,
9-
pub service: ServiceConfig,
10-
pub log: LogConfig,
15+
pub struct ArkimeConfig {
16+
net: NetConfig,
17+
service: ServiceConfig,
18+
log: LogConfig,
1119
}
1220

1321
#[derive(Serialize, Deserialize, Debug)]
1422
pub struct NetConfig {
15-
pub dynamic_interfaces: bool,
16-
pub bpf_filter: String,
17-
pub link_name: Vec<String>,
23+
dynamic_interfaces: bool,
24+
bpf_filter: String,
25+
link_name: Vec<String>,
1826
}
1927

2028
#[derive(Serialize, Deserialize, Debug)]
2129
pub struct ServiceConfig {
30+
hostname: String,
2231
host: String,
2332
port: u32,
33+
socket_path: String,
2434
}
2535

2636
#[derive(Serialize, Deserialize, Debug)]
@@ -29,30 +39,72 @@ pub struct LogConfig {
2939
output: String,
3040
}
3141

32-
impl Default for Config {
33-
fn default() -> Self {
34-
let file_path = "src/config.toml";
42+
lazy_static::lazy_static! {
43+
static ref SETTINGS: RwLock<Config> = RwLock::new({
44+
let settings = Config::builder()
45+
.add_source(config::Environment::with_prefix("ARKIME-RUST").separator("_"))
46+
.add_source(File::with_name(CONFIG_PATH));
47+
settings.build().unwrap()
48+
});
49+
}
3550

36-
let mut file = match File::open(file_path) {
37-
Ok(f) => f,
38-
Err(e) => panic!("error is op en conf {e}"),
39-
};
51+
fn watch() {
52+
thread::spawn(|| {
53+
let (tx, rx) = channel();
4054

41-
let mut str = String::new();
42-
match file.read_to_string(&mut str) {
43-
Ok(s) => s,
44-
Err(e) => panic!("error read str {}", e),
45-
};
55+
let mut watcher: RecommendedWatcher = Watcher::new(
56+
tx,
57+
notify::Config::default().with_poll_interval(Duration::from_secs(1000)),
58+
)
59+
.unwrap();
4660

47-
toml::from_str(&str).expect("parse config file failed")
48-
}
49-
}
61+
watcher
62+
.watch(
63+
Path::new(CONFIG_PATH),
64+
RecursiveMode::NonRecursive,
65+
)
66+
.unwrap();
67+
loop {
68+
match rx.recv() {
69+
Ok(Ok(Event {
70+
kind: notify::event::EventKind::Modify(_),
71+
..
72+
})) => {
73+
println!(" * Settings.toml written; refreshing configuration ...");
74+
SETTINGS.write().unwrap().refresh().unwrap();
75+
show();
76+
}
77+
78+
Err(e) => println!("watch error: {:?}", e),
5079

51-
impl Config {
52-
pub fn get<'a>() -> &'a Self {
53-
lazy_static! {
54-
static ref CACHE: Config = Config::default();
80+
_ => {
81+
// Ignore event
82+
}
83+
}
5584
}
56-
&CACHE
85+
});
86+
}
87+
88+
impl ArkimeConfig {
89+
90+
pub fn init() {
91+
SETTINGS.read().unwrap();
92+
watch();
93+
}
94+
95+
pub fn get_interface(self) -> Vec<String> {
96+
return self.net.link_name;
5797
}
5898
}
99+
100+
fn show() {
101+
println!(
102+
" * Settings :: \n\x1b[31m{:?}\x1b[0m",
103+
SETTINGS
104+
.read()
105+
.unwrap()
106+
.clone()
107+
.try_deserialize::<HashMap<String, String>>()
108+
.unwrap()
109+
);
110+
}

src/conf/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pub mod conf;
22

3-
pub use conf::Config;
3+
pub use conf::ArkimeConfig;

src/config.toml

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
[net]
2-
dynamic_interfaces = true
32
bpf_filter = ""
4-
link_name = ["lo"]
3+
dynamic_interfaces = true
4+
link_name = ["lo", "ens*"]
55

66
[service]
7+
hostname = ""
78
host = "127.0.0.1"
89
port = 8080
9-
10-
[core]
11-
hostname = ""
10+
socket_path = ""
1211

1312
[log]
1413
level = "info"
15-
output = "arkime.log"
14+
output = "arkime-rust.log"

src/main.rs

+14-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use std::process;
2-
3-
use capture::capture::Capture;
4-
use tokio::signal;
1+
use clap::Command;
52

63
mod capture;
74
mod cmd;
@@ -17,29 +14,19 @@ mod layer;
1714

1815
#[tokio::main]
1916
async fn main() {
20-
conf::Config::get();
21-
22-
// here to start handle interfaces and data capture
23-
tokio::spawn(async {
24-
init_capture();
25-
});
26-
match signal::ctrl_c().await {
27-
Ok(()) => {
28-
println!("bye!!!!");
29-
process::exit(0);
30-
}
31-
Err(err) => {
32-
eprintln!("Unable to listen for shutdown signal: {}", err);
33-
}
34-
}
35-
}
17+
let root_cmd = Command::new("arkime-rust").subcommands([
18+
cmd::capture::capture(),
19+
cmd::config::config(),
20+
cmd::reload::reload(),
21+
cmd::stop::stop(),
22+
cmd::version::version()
23+
]);
24+
let mut help_cmd = root_cmd.clone();
25+
let matches = root_cmd.get_matches();
3626

37-
fn init_capture() {
38-
let capture = Capture::new();
39-
match capture.run() {
40-
Ok(_) => {}
41-
Err(e) => {
42-
panic!("{}", e);
43-
}
27+
match matches.subcommand() {
28+
Some(("capture", capture_cmd)) => {},
29+
_ => help_cmd.print_help().unwrap()
4430
}
31+
conf::ArkimeConfig::init();
4532
}

0 commit comments

Comments
 (0)