configurable stored lists locations

This commit is contained in:
Jędrzej Stuczyński
2023-03-31 14:01:36 +01:00
parent 055ec4bdd5
commit f0e4d1a7cf
7 changed files with 82 additions and 38 deletions
+5 -2
View File
@@ -3,7 +3,7 @@
use futures::channel::mpsc;
use futures::StreamExt;
use notify::event::{DataChange, ModifyKind};
use notify::event::{DataChange, MetadataKind, ModifyKind};
use notify::{Config, Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
@@ -37,6 +37,7 @@ impl AsyncFileWatcher {
Some(vec![
EventKind::Modify(ModifyKind::Data(DataChange::Content)),
EventKind::Modify(ModifyKind::Data(DataChange::Any)),
EventKind::Modify(ModifyKind::Metadata(MetadataKind::Any)),
]),
None,
)
@@ -79,7 +80,7 @@ impl AsyncFileWatcher {
self
}
pub fn with_filter(mut self, filter: notify::EventKind) -> Self {
pub fn with_filter(mut self, filter: EventKind) -> Self {
match &mut self.filters {
None => {
self.filters = Some(vec![filter]);
@@ -133,6 +134,8 @@ impl AsyncFileWatcher {
if let Err(_err) = self.event_sender.unbounded_send(event) {
log::error!("the file watcher receiver has been dropped!");
}
} else {
log::debug!("will not propagate information about {:?}", event);
}
}
Err(err) => {
@@ -20,8 +20,17 @@ impl HostsStore {
///
/// You can inject a list of standard hosts that you want to support, in addition to the ones
/// in the user-defined storefile.
pub(crate) fn new(base_dir: PathBuf, filename: PathBuf) -> HostsStore {
let storefile = Self::setup_storefile(base_dir, filename);
pub(crate) fn new<P: AsRef<Path>>(storefile: P) -> HostsStore {
let storefile = storefile.as_ref().to_path_buf();
if !storefile.is_file() {
// there's no error handling in here and I'm not going to be changing it now.
panic!(
"the provided storefile {:?} is not a valid file!",
storefile
)
}
Self::setup_storefile(&storefile);
let hosts = Self::load_from_storefile(&storefile)
.unwrap_or_else(|_| panic!("Could not load hosts from storefile at {storefile:?}"));
@@ -77,25 +86,15 @@ impl HostsStore {
HostsStore::append(&self.storefile, host);
}
/// Returns the default base directory for the storefile.
///
/// This is split out so we can easily inject our own base_dir for unit tests.
pub fn default_base_dir() -> PathBuf {
dirs::home_dir()
.expect("no home directory known for this OS")
.join(".nym")
}
fn setup_storefile(base_dir: PathBuf, filename: PathBuf) -> PathBuf {
let dirpath = base_dir.join("service-providers").join("network-requester");
fs::create_dir_all(&dirpath)
.unwrap_or_else(|_| panic!("could not create storage directory at {dirpath:?}"));
let storefile = dirpath.join(filename);
let exists = std::path::Path::new(&storefile).exists();
if !exists {
File::create(&storefile).unwrap();
fn setup_storefile(file: &PathBuf) {
if !file.exists() {
let parent_dir = file
.parent()
.expect("parent dir does not exist for {file:?}");
fs::create_dir_all(&parent_dir)
.unwrap_or_else(|_| panic!("could not create storage directory at {parent_dir:?}"));
File::create(&file).unwrap();
}
storefile
}
/// Loads the storefile contents into memory.
@@ -18,8 +18,7 @@ pub(crate) struct StoredAllowedHosts {
impl StoredAllowedHosts {
pub(crate) fn new<P: AsRef<Path>>(path: P) -> Self {
let allowed_hosts =
HostsStore::new(HostsStore::default_base_dir(), path.as_ref().to_path_buf());
let allowed_hosts = HostsStore::new(path);
StoredAllowedHosts {
inner: Arc::new(RwLock::new(allowed_hosts)),
@@ -24,7 +24,11 @@ pub struct Config {
#[serde(flatten)]
base: BaseConfig<Config>,
pub debug: Debug,
#[serde(default)]
pub network_requester: NetworkRequster,
#[serde(default)]
pub network_requester_debug: Debug,
}
impl NymConfig for Config {
@@ -32,7 +36,6 @@ impl NymConfig for Config {
config_template()
}
// TODO: merge base dir with `HostStore`.
fn default_root_directory() -> PathBuf {
dirs::home_dir()
.expect("Failed to evaluate $HOME value")
@@ -66,6 +69,28 @@ impl ClientCoreConfigTrait for Config {
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct NetworkRequster {
/// Location of the file containing our allow.list
pub allowed_list_location: PathBuf,
/// Location of the file containing our unknown.list
pub unknown_list_location: PathBuf,
}
impl Default for NetworkRequster {
fn default() -> Self {
// same defaults as we had in <= v1.1.13
NetworkRequster {
allowed_list_location: <Config as NymConfig>::default_root_directory()
.join("allowed.list"),
unknown_list_location: <Config as NymConfig>::default_root_directory()
.join("unknown.list"),
}
}
}
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
#[serde(default, deny_unknown_fields)]
pub struct Debug {
@@ -84,10 +109,14 @@ impl Default for Debug {
impl Config {
pub fn new<S: Into<String>>(id: S) -> Self {
Config {
let mut cfg = Config {
base: BaseConfig::new(id),
debug: Default::default(),
}
..Default::default()
};
cfg.network_requester.allowed_list_location = cfg.data_directory().join("allowed.list");
cfg.network_requester.unknown_list_location = cfg.data_directory().join("unknown.list");
cfg
}
// getters
@@ -95,6 +124,14 @@ impl Config {
self.config_directory().join(Self::config_file_name())
}
pub fn allow_list_file_location(&self) -> PathBuf {
self.network_requester.allowed_list_location.clone()
}
pub fn unknown_list_file_location(&self) -> PathBuf {
self.network_requester.unknown_list_location.clone()
}
pub fn get_base(&self) -> &BaseConfig<Self> {
&self.base
}
@@ -54,7 +54,8 @@ impl From<OldConfigV1_1_13> for Config {
fn from(value: OldConfigV1_1_13) -> Self {
Config {
base: value.base.into(),
debug: Default::default(),
network_requester: Default::default(),
network_requester_debug: Default::default(),
}
}
}
@@ -76,6 +76,14 @@ gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
# Address of the gateway listener to which all client requests should be sent.
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
##### network requester specific config options #####
[network_requester]
# Location of the file containing our allow.list
allowed_list_location = '{{ network_requester.allowed_list_location }}'
# Location of the file containing our unknown.list
unknown_list_location = '{{ network_requester.unknown_list_location }}'
##### logging configuration options #####
@@ -31,7 +31,6 @@ use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_statistics_common::collector::StatisticsSender;
use nym_task::connections::LaneQueueLengths;
use nym_task::{TaskClient, TaskManager};
use std::path::PathBuf;
use std::sync::atomic::{AtomicUsize, Ordering};
// Since it's an atomic, it's safe to be kept static and shared across threads
@@ -160,12 +159,8 @@ impl NRServiceProviderBuilder {
) -> NRServiceProviderBuilder {
let standard_list = StandardList::new();
let allowed_hosts = StoredAllowedHosts::new("allowed.list");
let unknown_hosts = allowed_hosts::HostsStore::new(
allowed_hosts::HostsStore::default_base_dir(),
PathBuf::from("unknown.list"),
);
let allowed_hosts = StoredAllowedHosts::new(config.allow_list_file_location());
let unknown_hosts = allowed_hosts::HostsStore::new(config.unknown_list_file_location());
let outbound_request_filter =
OutboundRequestFilter::new(allowed_hosts.clone(), standard_list.clone(), unknown_hosts);
@@ -234,7 +229,9 @@ impl NRServiceProviderBuilder {
// start the standard list updater
StandardListUpdater::new(
self.config.debug.standard_list_update_interval,
self.config
.network_requester_debug
.standard_list_update_interval,
self.standard_list,
shutdown.subscribe(),
)