allow manual configuration update
This commit is contained in:
parent
b084ef5fed
commit
ba3b3a185f
|
@ -2,6 +2,5 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/dnapi" vcs="Git" />
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -2469,7 +2469,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tfclient"
|
name = "tfclient"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.0",
|
"base64 0.21.0",
|
||||||
"base64-serde",
|
"base64-serde",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tfclient"
|
name = "tfclient"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "An open-source reimplementation of a Defined Networking-compatible client"
|
description = "An open-source reimplementation of a Defined Networking-compatible client"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# The port that the tfclient daemon should listen on for JSON RPC requests.
|
||||||
|
listen_port = 8157
|
||||||
|
|
||||||
|
# Set this to true in order to disable automatic callbacks back to the API server.
|
||||||
|
# Use this if you are using an API server which you do not completley trust.
|
||||||
|
# If this is enabled, you'll need to run `tfclient --update` to manually update your client configuration.
|
||||||
|
disable_automatic_config_updates = false
|
|
@ -17,6 +17,7 @@ use crate::nebulaworker::NebulaWorkerMessage;
|
||||||
pub enum APIWorkerMessage {
|
pub enum APIWorkerMessage {
|
||||||
Shutdown,
|
Shutdown,
|
||||||
Enroll { code: String },
|
Enroll { code: String },
|
||||||
|
Update,
|
||||||
Timer
|
Timer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ pub fn apiworker_main(_config: TFClientConfig, instance: String, url: String, tx
|
||||||
info!("recv on command socket: shutdown, stopping");
|
info!("recv on command socket: shutdown, stopping");
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
APIWorkerMessage::Timer => {
|
APIWorkerMessage::Timer | APIWorkerMessage::Update => {
|
||||||
info!("updating config");
|
info!("updating config");
|
||||||
let mut cdata = match load_cdata(&instance) {
|
let mut cdata = match load_cdata(&instance) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
|
|
|
@ -18,7 +18,9 @@ fn default_port() -> u16 { DEFAULT_PORT }
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct TFClientConfig {
|
pub struct TFClientConfig {
|
||||||
#[serde(default = "default_port")]
|
#[serde(default = "default_port")]
|
||||||
pub listen_port: u16
|
pub listen_port: u16,
|
||||||
|
#[serde(default = "bool_false")]
|
||||||
|
pub disable_automatic_config_updates: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -33,7 +35,8 @@ pub fn create_config(instance: &str) -> Result<(), Box<dyn Error>> {
|
||||||
fs::create_dir_all(get_config_dir(instance).ok_or("Unable to load config dir")?)?;
|
fs::create_dir_all(get_config_dir(instance).ok_or("Unable to load config dir")?)?;
|
||||||
info!("Copying default config file to config directory...");
|
info!("Copying default config file to config directory...");
|
||||||
let config = TFClientConfig {
|
let config = TFClientConfig {
|
||||||
listen_port: DEFAULT_PORT
|
listen_port: DEFAULT_PORT,
|
||||||
|
disable_automatic_config_updates: false,
|
||||||
};
|
};
|
||||||
let config_str = toml::to_string(&config)?;
|
let config_str = toml::to_string(&config)?;
|
||||||
fs::write(get_config_file(instance).ok_or("Unable to load config dir")?, config_str)?;
|
fs::write(get_config_file(instance).ok_or("Unable to load config dir")?, config_str)?;
|
||||||
|
|
|
@ -95,10 +95,23 @@ pub fn daemon_main(name: String, server: String) {
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("Starting timer thread...");
|
info!("Starting timer thread...");
|
||||||
|
if !config.disable_automatic_config_updates {
|
||||||
let timer_transmitter = transmitter.clone();
|
let timer_transmitter = transmitter.clone();
|
||||||
let timer_thread = thread::spawn(move || {
|
let timer_thread = thread::spawn(move || {
|
||||||
timer_main(timer_transmitter, rx_timer);
|
timer_main(timer_transmitter, rx_timer);
|
||||||
});
|
});
|
||||||
|
info!("Waiting for timer thread to exit...");
|
||||||
|
match timer_thread.join() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(_) => {
|
||||||
|
error!("Error waiting for timer thread to exit.");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info!("Timer thread exited");
|
||||||
|
} else {
|
||||||
|
info!("automatic config updates have been disabled - not starting timer thread");
|
||||||
|
}
|
||||||
|
|
||||||
info!("Starting socket worker thread...");
|
info!("Starting socket worker thread...");
|
||||||
let name_socket = name.clone();
|
let name_socket = name.clone();
|
||||||
|
@ -126,16 +139,6 @@ pub fn daemon_main(name: String, server: String) {
|
||||||
}
|
}
|
||||||
info!("API thread exited");
|
info!("API thread exited");
|
||||||
|
|
||||||
info!("Waiting for timer thread to exit...");
|
|
||||||
match timer_thread.join() {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(_) => {
|
|
||||||
error!("Error waiting for timer thread to exit.");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info!("Timer thread exited");
|
|
||||||
|
|
||||||
info!("Waiting for Nebula thread to exit...");
|
info!("Waiting for Nebula thread to exit...");
|
||||||
match nebula_thread.join() {
|
match nebula_thread.join() {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
|
|
@ -123,6 +123,13 @@ enum Commands {
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
/// Enrollment code used to enroll this node
|
/// Enrollment code used to enroll this node
|
||||||
code: String,
|
code: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Manually trigger a config update. It's useful to use this in combination with the `disable_automatic_config_updates` option.
|
||||||
|
Update {
|
||||||
|
#[clap(short, long, default_value = "tfclient")]
|
||||||
|
/// Service name specified on install
|
||||||
|
name: String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +254,23 @@ fn main() {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
Commands::Update { name } => {
|
||||||
|
info!("Loading config...");
|
||||||
|
let config = match load_config(&name) {
|
||||||
|
Ok(cfg) => cfg,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error loading configuration: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match socketclient::update(&config) {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error sending update request: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,49 @@ pub fn enroll(code: &str, config: &TFClientConfig) -> Result<(), Box<dyn Error>>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update(config: &TFClientConfig) -> Result<(), Box<dyn Error>> {
|
||||||
|
info!("Connecting to local command socket...");
|
||||||
|
let mut stream = TcpStream::connect(SocketAddr::new(IpAddr::from([127, 0, 0, 1]), config.listen_port))?;
|
||||||
|
let stream2 = stream.try_clone()?;
|
||||||
|
let mut reader = BufReader::new(&stream2);
|
||||||
|
|
||||||
|
info!("Sending Hello...");
|
||||||
|
stream.write_all(&ctob(JsonMessage::Hello {
|
||||||
|
version: JSON_API_VERSION,
|
||||||
|
}))?;
|
||||||
|
info!("Waiting for hello...");
|
||||||
|
let msg = read_msg(&mut reader)?;
|
||||||
|
match msg {
|
||||||
|
JsonMessage::Hello { .. } => {
|
||||||
|
info!("Server sent hello, connection established")
|
||||||
|
}
|
||||||
|
JsonMessage::Goodbye { reason } => {
|
||||||
|
error!("Disconnected by server. Reason: {:?}", reason);
|
||||||
|
return Err("Disconnected by server".into());
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Server returned unexpected message: {:?}", msg);
|
||||||
|
error!("Sending goodbye and exiting");
|
||||||
|
stream.write_all(&ctob(JsonMessage::Goodbye {
|
||||||
|
reason: DisconnectReason::UnexpectedMessageType,
|
||||||
|
}))?;
|
||||||
|
return Err("Unexpected message type by server".into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Sending enroll request...");
|
||||||
|
stream.write_all(&ctob(JsonMessage::Update {}))?;
|
||||||
|
|
||||||
|
info!("Sending disconnect...");
|
||||||
|
stream.write_all(&ctob(JsonMessage::Goodbye {
|
||||||
|
reason: DisconnectReason::Done,
|
||||||
|
}))?;
|
||||||
|
|
||||||
|
info!("Told tfclient daemon to trigger a configuration update. Check tfclient's logs to see if this was successful.");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn read_msg(reader: &mut BufReader<&TcpStream>) -> Result<JsonMessage, Box<dyn Error>> {
|
fn read_msg(reader: &mut BufReader<&TcpStream>) -> Result<JsonMessage, Box<dyn Error>> {
|
||||||
let mut str = String::new();
|
let mut str = String::new();
|
||||||
reader.read_line(&mut str)?;
|
reader.read_line(&mut str)?;
|
||||||
|
|
|
@ -241,6 +241,12 @@ fn senthello_handle(client: &mut Client, transmitter: &ThreadMessageSender, comm
|
||||||
info!("Client sent enroll with code {}", code);
|
info!("Client sent enroll with code {}", code);
|
||||||
info!("Sending enroll request to apiworker");
|
info!("Sending enroll request to apiworker");
|
||||||
transmitter.api_thread.send(APIWorkerMessage::Enroll { code }).unwrap();
|
transmitter.api_thread.send(APIWorkerMessage::Enroll { code }).unwrap();
|
||||||
|
},
|
||||||
|
|
||||||
|
JsonMessage::Update {} => {
|
||||||
|
info!("Client sent update request.");
|
||||||
|
info!("Telling apiworker to update configuration");
|
||||||
|
transmitter.api_thread.send(APIWorkerMessage::Update).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -290,7 +296,9 @@ pub enum JsonMessage {
|
||||||
#[serde(rename = "enroll")]
|
#[serde(rename = "enroll")]
|
||||||
Enroll {
|
Enroll {
|
||||||
code: String
|
code: String
|
||||||
}
|
},
|
||||||
|
#[serde(rename = "update")]
|
||||||
|
Update {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
|
Loading…
Reference in New Issue