allow manual configuration update

This commit is contained in:
core 2023-03-30 17:34:00 -04:00
parent b084ef5fed
commit ba3b3a185f
Signed by: core
GPG Key ID: FDBF740DADDCEECF
10 changed files with 109 additions and 21 deletions

View File

@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/dnapi" vcs="Git" />
</component>
</project>

2
Cargo.lock generated
View File

@ -2469,7 +2469,7 @@ dependencies = [
[[package]]
name = "tfclient"
version = "0.1.1"
version = "0.1.2"
dependencies = [
"base64 0.21.0",
"base64-serde",

View File

@ -1,6 +1,6 @@
[package]
name = "tfclient"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
description = "An open-source reimplementation of a Defined Networking-compatible client"
license = "GPL-3.0-or-later"

View File

@ -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

View File

@ -17,6 +17,7 @@ use crate::nebulaworker::NebulaWorkerMessage;
pub enum APIWorkerMessage {
Shutdown,
Enroll { code: String },
Update,
Timer
}
@ -33,7 +34,7 @@ pub fn apiworker_main(_config: TFClientConfig, instance: String, url: String, tx
info!("recv on command socket: shutdown, stopping");
break;
},
APIWorkerMessage::Timer => {
APIWorkerMessage::Timer | APIWorkerMessage::Update => {
info!("updating config");
let mut cdata = match load_cdata(&instance) {
Ok(c) => c,

View File

@ -18,7 +18,9 @@ fn default_port() -> u16 { DEFAULT_PORT }
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TFClientConfig {
#[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)]
@ -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")?)?;
info!("Copying default config file to config directory...");
let config = TFClientConfig {
listen_port: DEFAULT_PORT
listen_port: DEFAULT_PORT,
disable_automatic_config_updates: false,
};
let config_str = toml::to_string(&config)?;
fs::write(get_config_file(instance).ok_or("Unable to load config dir")?, config_str)?;

View File

@ -95,10 +95,23 @@ pub fn daemon_main(name: String, server: String) {
});
info!("Starting timer thread...");
let timer_transmitter = transmitter.clone();
let timer_thread = thread::spawn(move || {
timer_main(timer_transmitter, rx_timer);
});
if !config.disable_automatic_config_updates {
let timer_transmitter = transmitter.clone();
let timer_thread = thread::spawn(move || {
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...");
let name_socket = name.clone();
@ -126,16 +139,6 @@ pub fn daemon_main(name: String, server: String) {
}
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...");
match nebula_thread.join() {
Ok(_) => (),

View File

@ -123,6 +123,13 @@ enum Commands {
#[clap(short, long)]
/// Enrollment code used to enroll this node
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);
}
};
},
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);
}
};
}
}
}

View File

@ -50,6 +50,49 @@ pub fn enroll(code: &str, config: &TFClientConfig) -> Result<(), Box<dyn Error>>
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>> {
let mut str = String::new();
reader.read_line(&mut str)?;

View File

@ -241,6 +241,12 @@ fn senthello_handle(client: &mut Client, transmitter: &ThreadMessageSender, comm
info!("Client sent enroll with code {}", code);
info!("Sending enroll request to apiworker");
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")]
Enroll {
code: String
}
},
#[serde(rename = "update")]
Update {}
}
#[derive(Serialize, Deserialize, Debug)]