198 lines
6.6 KiB
Rust
198 lines
6.6 KiB
Rust
// Code to handle the nebula worker
|
|
|
|
use crate::config::{load_cdata, NebulaConfig, TFClientConfig};
|
|
use crate::daemon::ThreadMessageSender;
|
|
use crate::dirs::{nebula_yml};
|
|
use log::{debug, error, info};
|
|
use std::error::Error;
|
|
use std::fs;
|
|
use std::sync::mpsc::Receiver;
|
|
use nebula_ffi::NebulaInstance;
|
|
use crate::util::shutdown;
|
|
|
|
pub enum NebulaWorkerMessage {
|
|
Shutdown,
|
|
ConfigUpdated,
|
|
WakeUp,
|
|
}
|
|
|
|
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
|
|
if !nebula_yml(instance).exists() {
|
|
return Ok(()); // cant insert private key into a file that does not exist - BUT. we can gracefully handle nebula crashing - we cannot gracefully handle this fn failing
|
|
}
|
|
let cdata = load_cdata(instance)?;
|
|
let key = cdata.dh_privkey.ok_or("Missing private key")?;
|
|
|
|
let config_str = fs::read_to_string(
|
|
nebula_yml(instance),
|
|
)?;
|
|
let mut config: NebulaConfig = serde_yaml::from_str(&config_str)?;
|
|
|
|
config.pki.key = Some(String::from_utf8(key)?);
|
|
|
|
debug!("inserted private key into config: {:?}", config);
|
|
|
|
let config_str = serde_yaml::to_string(&config)?;
|
|
fs::write(
|
|
nebula_yml(instance),
|
|
config_str,
|
|
)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn nebulaworker_main(
|
|
_config: TFClientConfig,
|
|
instance: String,
|
|
transmitter: ThreadMessageSender,
|
|
rx: Receiver<NebulaWorkerMessage>,
|
|
) {
|
|
let cdata = match load_cdata(&instance) {
|
|
Ok(data) => data,
|
|
Err(e) => {
|
|
error!("unable to load cdata: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
return;
|
|
}
|
|
};
|
|
|
|
info!("fixing config...");
|
|
match insert_private_key(&instance) {
|
|
Ok(_) => {
|
|
info!("config fixed (private-key embedded)");
|
|
}
|
|
Err(e) => {
|
|
error!("unable to fix config: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
return;
|
|
}
|
|
}
|
|
|
|
let mut nebula: Option<NebulaInstance> = None;
|
|
|
|
if cdata.creds.is_none() {
|
|
error!("not enrolled, cannot start nebula");
|
|
} else {
|
|
info!("setting up nebula...");
|
|
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
|
|
Ok(i) => {
|
|
info!("nebula setup");
|
|
info!("starting nebula...");
|
|
match i.start() {
|
|
Ok(_) => (),
|
|
Err(e) => {
|
|
error!("error starting Nebula: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
}
|
|
|
|
i
|
|
},
|
|
Err(e) => {
|
|
error!("error setting up Nebula: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
|
|
});
|
|
info!("nebula process started");
|
|
}
|
|
|
|
loop {
|
|
match rx.recv() {
|
|
Ok(msg) => match msg {
|
|
NebulaWorkerMessage::WakeUp => {
|
|
continue;
|
|
}
|
|
NebulaWorkerMessage::Shutdown => {
|
|
info!("recv on command socket: shutdown, stopping");
|
|
info!("shutting down nebula");
|
|
|
|
if let Some(i) = nebula.as_ref() {
|
|
match i.stop() {
|
|
Ok(_) => (),
|
|
Err(e) => {
|
|
error!("error stopping Nebula: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
info!("nebula shut down");
|
|
break;
|
|
}
|
|
NebulaWorkerMessage::ConfigUpdated => {
|
|
info!("our configuration has been updated - reloading");
|
|
|
|
debug!("fixing config...");
|
|
match insert_private_key(&instance) {
|
|
Ok(_) => {
|
|
debug!("config fixed (private-key embedded)");
|
|
}
|
|
Err(e) => {
|
|
error!("unable to fix config: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
return;
|
|
}
|
|
}
|
|
|
|
if let Some(i) = nebula.as_ref() {
|
|
debug!("reloading nebula");
|
|
|
|
match i.reload_config() {
|
|
Ok(_) => (),
|
|
Err(e) => {
|
|
error!("error reloading Nebula config: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
}
|
|
|
|
debug!("config reloaded");
|
|
} else {
|
|
debug!("detected enrollment, starting nebula for the first time");
|
|
info!("setting up nebula...");
|
|
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
|
|
Ok(i) => {
|
|
info!("nebula setup");
|
|
info!("starting nebula...");
|
|
match i.start() {
|
|
Ok(_) => (),
|
|
Err(e) => {
|
|
error!("error starting Nebula: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
}
|
|
|
|
i
|
|
},
|
|
Err(e) => {
|
|
error!("error setting up Nebula: {}", e);
|
|
error!("nebula thread exiting with error");
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
|
|
});
|
|
info!("nebula process started");
|
|
}
|
|
|
|
debug!("nebula process reloaded");
|
|
}
|
|
},
|
|
Err(e) => {
|
|
error!("nebulaworker command socket errored: {}", e);
|
|
shutdown(&transmitter);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|