allow manual configuration update
This commit is contained in:
parent
b084ef5fed
commit
ba3b3a185f
|
@ -2,6 +2,5 @@
|
|||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/dnapi" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -2469,7 +2469,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tfclient"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"base64-serde",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
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,
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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(_) => (),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)]
|
||||
|
|
Loading…
Reference in New Issue