Change settings to be done in the config directory

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent 033e78a680
commit 12f82e72f0
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

4
.gitignore vendored

@ -1,4 +1,6 @@
/target
.idea
*.env
test
test
config
nodes

172
Cargo.lock generated

@ -33,6 +33,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "atty"
version = "0.2.14"
@ -126,7 +132,7 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"num-traits 0.2.14",
"time",
"winapi",
]
@ -175,6 +181,22 @@ dependencies = [
"winapi",
]
[[package]]
name = "config"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3"
dependencies = [
"lazy_static",
"nom",
"rust-ini",
"serde 1.0.117",
"serde-hjson",
"serde_json",
"toml",
"yaml-rust",
]
[[package]]
name = "const_fn"
version = "0.4.3"
@ -235,12 +257,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "env_logger"
version = "0.8.1"
@ -287,6 +303,12 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hashbrown"
version = "0.9.1"
@ -349,12 +371,31 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "itoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexical-core"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 0.1.10",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.80"
@ -371,6 +412,22 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "linked-hash-map"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
dependencies = [
"serde 0.8.23",
"serde_test",
]
[[package]]
name = "linked-hash-map"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
[[package]]
name = "lock_api"
version = "0.4.1"
@ -423,6 +480,17 @@ dependencies = [
"libc",
]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "num-integer"
version = "0.1.44"
@ -430,7 +498,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
"num-traits 0.2.14",
]
[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
dependencies = [
"num-traits 0.2.14",
]
[[package]]
@ -609,7 +686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f10b46df14cf1ee1ac7baa4d2fbc2c52c0622a4b82fa8740e37bc452ac0184f"
dependencies = [
"byteorder",
"num-traits",
"num-traits 0.2.14",
]
[[package]]
@ -620,7 +697,7 @@ checksum = "4ce7d70c926fe472aed493b902010bccc17fa9f7284145cb8772fd22fdb052d8"
dependencies = [
"byteorder",
"rmp",
"serde",
"serde 1.0.117",
]
[[package]]
@ -638,6 +715,18 @@ dependencies = [
"smallvec",
]
[[package]]
name = "rust-ini"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "salsa20"
version = "0.7.1"
@ -663,6 +752,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
[[package]]
name = "serde"
version = "1.0.117"
@ -672,6 +767,19 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde-hjson"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
dependencies = [
"lazy_static",
"linked-hash-map 0.3.0",
"num-traits 0.1.43",
"regex",
"serde 0.8.23",
]
[[package]]
name = "serde_derive"
version = "1.0.117"
@ -683,6 +791,26 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
dependencies = [
"itoa",
"ryu",
"serde 1.0.117",
]
[[package]]
name = "serde_test"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5"
dependencies = [
"serde 0.8.23",
]
[[package]]
name = "sha2"
version = "0.9.2"
@ -709,19 +837,26 @@ dependencies = [
"base64",
"chrono",
"colored",
"dotenv",
"config",
"env_logger",
"glob",
"hostname",
"log",
"mac_address",
"rand",
"rusqlite",
"serde",
"serde 1.0.117",
"structopt",
"toml",
"vented",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.8.0"
@ -825,7 +960,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645"
dependencies = [
"serde",
"serde 1.0.117",
]
[[package]]
@ -890,7 +1025,7 @@ dependencies = [
"rmp",
"rmp-serde",
"scheduled-thread-pool",
"serde",
"serde 1.0.117",
"sha2",
"typenum",
"x25519-dalek",
@ -970,6 +1105,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "yaml-rust"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
dependencies = [
"linked-hash-map 0.5.3",
]
[[package]]
name = "zeroize"
version = "1.1.1"

@ -12,7 +12,6 @@ rusqlite = "0.24.1"
rand = "0.7.3"
base64 = "0.13.0"
structopt = "0.3.20"
dotenv = "0.15.0"
mac_address = "1.1.1"
hostname = "0.3.1"
log = "0.4.11"
@ -20,4 +19,6 @@ env_logger = "0.8.1"
colored = "2.0.0"
chrono = "0.4.19"
toml = "0.5.7"
serde = { version = "1.0.117", features = ["serde_derive"] }
serde = { version = "1.0.117", features = ["serde_derive"] }
config = "0.10.1"
glob = "0.3.0"

@ -23,18 +23,9 @@ When run without a subcommand the server executes normally.
## Configuration
Basic server configuration is done in .env files.
|Variable | Description | Default Value |
|--------|----------|---------------|
| SNEKCLOUD_NODES_DIR | Directory containing the .toml files for the network nodes| nodes |
| SNEKCLOUD_PRIVATE_KEY | Path of the private key (generated with generate-key) | node_key |
| SNEKCLOUD_LISTEN_ADDRESS | The address the server listens on | 127.0.0.1:22222 |
| SNEKCLOUD_NODE_ID | The NodeID of the instance | None |
The NodeID is a parameter that can either be set manually or is generated
from the mac-address or hostname depending on what is available.
The configuration for the server has to be done in the config directory.
This directory will always contain the default configuration `default.toml` and will
load additional files with the same ending.
## License

@ -4,20 +4,21 @@ use crate::utils::keys::{armor_public_key, extract_public_key};
use std::path::PathBuf;
use crate::utils::result::SnekcloudResult;
use std::fs;
use crate::utils::write_toml_pretty;
#[derive(Serialize, Deserialize)]
pub struct NodeData {
pub id: String,
pub address: Option<String>,
pub addresses: Vec<String>,
public_key: String,
}
impl NodeData {
pub fn with_address(id: String, address: String, public_key: PublicKey) -> Self {
pub fn with_addresses(id: String, addresses: Vec<String>, public_key: PublicKey) -> Self {
let public_key = armor_public_key(public_key);
Self {
id,
address: Some(address),
addresses,
public_key
}
}
@ -32,10 +33,7 @@ impl NodeData {
/// Writes the data to the given file
pub fn write_to_file(&self, path: PathBuf) -> SnekcloudResult<()> {
let content = toml::to_string(self)?;
fs::write(path, content.as_bytes())?;
Ok(())
write_toml_pretty(&path, self)
}
pub fn public_key(&self) -> PublicKey {

@ -1,6 +1,5 @@
use crate::server::SnekcloudServer;
use crate::utils::get_node_id;
use crate::utils::env::{get_private_key_path, get_key_file_storage, get_listen_address};
use crate::utils::settings::{Settings, get_settings};
use crate::utils::keys::{extract_private_key, read_node_keys, generate_private_key, armor_private_key};
use std::path::PathBuf;
use crate::utils::result::SnekcloudResult;
@ -13,6 +12,7 @@ use crate::data::node_data::NodeData;
pub(crate) mod utils;
pub(crate) mod server;
pub(crate) mod data;
pub(crate) mod modules;
#[derive(StructOpt, Debug)]
struct Opt {
@ -47,6 +47,8 @@ struct WriteInfoFileOptions {
fn main() -> SnekcloudResult<()>{
init_logger();
let opt: Opt = Opt::from_args();
let settings = get_settings()?;
if let Some(command) = opt.sub_command {
match command {
SubCommand::GenerateKey(options) => {
@ -55,27 +57,30 @@ fn main() -> SnekcloudResult<()>{
fs::write(options.output_file, string_content)?;
},
SubCommand::WriteInfoFile(options) => {
let key = get_private_key()?;
let data = NodeData::with_address(get_node_id(), get_listen_address(), key.public_key());
let key = get_private_key(&settings)?;
let data = NodeData::with_addresses(settings.node_id, settings.listen_addresses, key.public_key());
data.write_to_file(options.output_file)?;
}
}
} else {
start_server(opt)?;
start_server(opt, &settings)?;
}
Ok(())
}
fn start_server(_options: Opt) -> SnekcloudResult<()> {
let keys = read_node_keys(&PathBuf::from(get_key_file_storage()))?;
let mut server = SnekcloudServer::new(get_node_id(), get_private_key()?, keys, 8);
server.add_listen_address(get_listen_address());
fn start_server(_options: Opt, settings: &Settings) -> SnekcloudResult<()> {
let keys = read_node_keys(&settings.node_data_dir)?;
let mut server = SnekcloudServer::new(settings.node_id.clone(), get_private_key(settings)?, keys, 8);
for address in &settings.listen_addresses {
server.add_listen_address(address.clone());
}
server.run()?;
Ok(())
}
fn get_private_key() -> SnekcloudResult<SecretKey> {
extract_private_key(&fs::read_to_string(get_private_key_path())?)
fn get_private_key(settings: &Settings) -> SnekcloudResult<SecretKey> {
extract_private_key(&fs::read_to_string(&settings.private_key)?)
}

@ -0,0 +1,6 @@
use vented::server::VentedServer;
use crate::utils::result::SnekcloudResult;
pub trait Module {
fn init(&mut self, server: &VentedServer) -> SnekcloudResult<()>;
}

@ -3,6 +3,7 @@ use crate::utils::result::SnekcloudResult;
use vented::crypto::SecretKey;
use vented::server::data::Node;
use vented::WaitGroup;
use crate::modules::Module;
pub struct SnekcloudServer {
inner: VentedServer,
@ -33,4 +34,9 @@ impl SnekcloudServer {
Ok(())
}
/// Registers a module on the server
pub fn register_module(&mut self, module: &mut impl Module) -> SnekcloudResult<()> {
module.init(&mut self.inner)
}
}

@ -1,20 +0,0 @@
const VAR_KEY_FILE_STORAGE: &str = "SNEKCLOUD_NODES_DIR";
const VAR_PRIVATE_KEY_PATH: &str = "SNEKCLOUD_PRIVATE_KEY";
const VAR_LISTEN_ADDRESS: &str = "SNEKCLOUD_LISTEN_ADDRESS";
const VAR_NODE_ID: &str = "SNEKCLOUD_NODE_ID";
pub fn get_key_file_storage() -> String {
dotenv::var(VAR_KEY_FILE_STORAGE).unwrap_or("nodes".to_string())
}
pub fn get_private_key_path() -> String {
dotenv::var(VAR_PRIVATE_KEY_PATH).unwrap_or("node_key".to_string())
}
pub fn get_env_node_id() -> Option<String> {
dotenv::var(VAR_NODE_ID).ok()
}
pub fn get_listen_address() -> String {
dotenv::var(VAR_LISTEN_ADDRESS).unwrap_or("127.0.0.1:22222".to_string())
}

@ -1,8 +1,9 @@
use std::path::PathBuf;
use std::path::{PathBuf, Path};
use vented::crypto::{SecretKey, PublicKey};
use crate::utils::result::{SnekcloudResult, SnekcloudError};
use vented::server::data::Node;
use crate::data::node_data::NodeData;
use std::fs::create_dir;
const PRIVATE_KEY_HEADER_LINE: &str = "---BEGIN-SNEKCLOUD-PRIVATE-KEY---\n";
const PRIVATE_KEY_FOOTER_LINE: &str = "\n---END-SNEKCLOUD-PRIVATE-KEY---";
@ -12,6 +13,9 @@ const PUBLIC_KEY_FOOTER_LINE: &str = "\n---END-SNEKCLOUD-PUBLIC-KEY---";
/// Reads a folder of node public keys
pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult<Vec<Node>> {
if !Path::new(path).exists() {
create_dir(path)?;
}
let dir_content = path.read_dir()?;
let content = dir_content
@ -22,9 +26,9 @@ pub fn read_node_keys(path: &PathBuf) -> SnekcloudResult<Vec<Node>> {
})
.filter(|(meta, _)|meta.is_file())
.filter_map(|(_, entry)|{
let data = NodeData::from_file(entry.path()).ok()?;
let mut data = NodeData::from_file(entry.path()).ok()?;
Some(Node {public_key: data.public_key(), address: data.address, id: data.id})
Some(Node {public_key: data.public_key(), address: data.addresses.pop(), id: data.id})
}).collect();
Ok(content)

@ -1,16 +1,18 @@
use crate::utils::env::get_env_node_id;
use rand::RngCore;
use std::path::PathBuf;
use crate::utils::result::SnekcloudResult;
use serde::Serialize;
use std::fs;
pub mod result;
pub mod keys;
pub mod env;
pub mod settings;
pub mod logging;
pub fn get_node_id() -> String {
if let Some(id) = get_env_node_id() {
log::trace!("Using env node_id");
id
} else if let Ok(Some(address)) = mac_address::get_mac_address() {
if let Ok(Some(address)) = mac_address::get_mac_address() {
log::trace!("Using mac address as node_id");
base64::encode(address.bytes())
} else if let Ok(hostname) = hostname::get() {
@ -24,4 +26,14 @@ pub fn get_node_id() -> String {
base64::encode(id_raw)
}
}
/// Writes a pretty toml file to the given path
pub fn write_toml_pretty<T: Serialize>(path: &PathBuf, value: &T) -> SnekcloudResult<()> {
let mut buf_str = String::new();
let mut serializer = toml::Serializer::pretty(&mut buf_str);
value.serialize(&mut serializer)?;
fs::write(path, buf_str.as_bytes())?;
Ok(())
}

@ -14,6 +14,8 @@ pub enum SnekcloudError {
TomlDeserializeError(toml::de::Error),
TomlSerializeError(toml::ser::Error),
InvalidKey,
ConfigError(config::ConfigError),
GlobPatternError(glob::PatternError),
}
impl fmt::Display for SnekcloudError {
@ -25,6 +27,8 @@ impl fmt::Display for SnekcloudError {
Self::InvalidKey => write!(f, "Invalid Key!"),
Self::TomlDeserializeError(e) => write!(f, "Toml Deserialization Error: {}", e),
Self::TomlSerializeError(e) => write!(f, "Toml Serialization Error: {}", e),
Self::ConfigError(e) => write!(f, "Config Error: {}",e),
Self::GlobPatternError(e) => write!(f, "Glob Error {}", e),
}
}
}
@ -50,13 +54,25 @@ impl From<base64::DecodeError> for SnekcloudError {
}
impl From<toml::ser::Error> for SnekcloudError {
fn from(other: toml::ser::Error) -> Self {
Self::TomlSerializeError(other)
fn from(error: toml::ser::Error) -> Self {
Self::TomlSerializeError(error)
}
}
impl From<toml::de::Error> for SnekcloudError {
fn from(other: toml::de::Error) -> Self {
Self::TomlDeserializeError(other)
fn from(error: toml::de::Error) -> Self {
Self::TomlDeserializeError(error)
}
}
impl From<config::ConfigError> for SnekcloudError {
fn from(error: config::ConfigError) -> Self {
Self::ConfigError(error)
}
}
impl From<glob::PatternError> for SnekcloudError {
fn from(error: glob::PatternError) -> Self {
Self::GlobPatternError(error)
}
}

@ -0,0 +1,48 @@
use crate::utils::result::{SnekcloudResult, SnekcloudError};
use serde::{Serialize, Deserialize};
use crate::utils::{get_node_id, write_toml_pretty};
use std::fs;
use std::path::{Path, PathBuf};
use config::File;
const CONFIG_DIR: &str = "config/";
const DEFAULT_CONFIG: &str = "config/00_default.toml";
const GLOB_CONFIG: &str = "config/*.toml";
const ENV_PREFIX : &str = "SNEKCLOUD";
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Settings {
pub listen_addresses: Vec<String>,
pub node_id: String,
pub private_key: PathBuf,
pub node_data_dir: PathBuf,
}
impl Default for Settings {
fn default() -> Self {
Self {
listen_addresses: vec!["127.0.0.1:22222".to_string()],
node_id: get_node_id(),
private_key: PathBuf::from("node_key"),
node_data_dir: PathBuf::from("nodes"),
}
}
}
pub fn get_settings() -> SnekcloudResult<Settings> {
if !Path::new(CONFIG_DIR).exists() {
fs::create_dir(CONFIG_DIR)?;
}
write_toml_pretty(&PathBuf::from(DEFAULT_CONFIG), &Settings::default())?;
let mut settings = config::Config::default();
settings
.merge(config::File::with_name(DEFAULT_CONFIG))?
.merge(glob::glob(GLOB_CONFIG)?.map(|path| File::from(path.unwrap()))
.collect::<Vec<_>>())?
.merge(config::Environment::with_prefix(ENV_PREFIX))?;
settings.try_into().map_err(SnekcloudError::from)
}
Loading…
Cancel
Save