-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #208 from holochain/fix/holo-align-networking
Align networking params with Holo
- Loading branch information
Showing
8 changed files
with
215 additions
and
127 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,150 +1,215 @@ | ||
#![deny(clippy::all)] | ||
|
||
use holochain_conductor_api::{ | ||
conductor::{paths::DataRootPath, ConductorConfig, KeystoreConfig}, | ||
AdminInterfaceConfig, InterfaceDriver, | ||
conductor::{paths::DataRootPath, ConductorConfig, KeystoreConfig}, | ||
AdminInterfaceConfig, InterfaceDriver, | ||
}; | ||
use holochain_p2p::kitsune_p2p::dependencies::kitsune_p2p_types::config::{ | ||
tuning_params_struct::KitsuneP2pTuningParams, KitsuneP2pConfig, TransportConfig, | ||
}; | ||
use holochain_p2p::kitsune_p2p::dependencies::kitsune_p2p_types::config::{tuning_params_struct::KitsuneP2pTuningParams, KitsuneP2pConfig, TransportConfig}; | ||
use holochain_types::websocket::AllowedOrigins; | ||
use napi::{Error, Result, Status}; | ||
use napi_derive::napi; | ||
use serde_yaml::{Mapping, Value}; | ||
use serde_yaml::{Mapping, Sequence, Value}; | ||
use std::{collections::HashSet, path::PathBuf}; | ||
|
||
fn create_error(msg: &str) -> Error { | ||
Error::new(Status::GenericFailure, String::from(msg)) | ||
Error::new(Status::GenericFailure, String::from(msg)) | ||
} | ||
|
||
fn insert_mapping(mapping: &mut Mapping, key: &str, value: Value) { | ||
mapping.insert(Value::String(String::from(key)), value); | ||
mapping.insert(Value::String(String::from(key)), value); | ||
} | ||
|
||
fn create_mapping_with_entries(entries: Vec<(&str, Value)>) -> Mapping { | ||
let mut mapping = Mapping::new(); | ||
for (key, value) in entries { | ||
insert_mapping(&mut mapping, key, value); | ||
} | ||
mapping | ||
let mut mapping = Mapping::new(); | ||
for (key, value) in entries { | ||
insert_mapping(&mut mapping, key, value); | ||
} | ||
mapping | ||
} | ||
|
||
fn webrtc_config_from_ice_urls(ice_server_urls: Vec<String>) -> serde_json::Value { | ||
let mut webrtc_config = serde_json::Map::new(); | ||
let mut ice_servers = Vec::new(); | ||
for url in ice_server_urls { | ||
let mut url_mapping = serde_json::Map::new(); | ||
url_mapping.insert( | ||
String::from("urls"), | ||
serde_json::Value::Array(vec![serde_json::Value::String(url)]), | ||
); | ||
ice_servers.push(serde_json::Value::Object(url_mapping)); | ||
} | ||
webrtc_config.insert( | ||
String::from("ice_servers"), | ||
serde_json::Value::Array(ice_servers), | ||
); | ||
serde_json::Value::Object(webrtc_config) | ||
} | ||
|
||
#[napi] | ||
pub fn overwrite_config( | ||
admin_port: u16, | ||
keystore_connection_url: String, | ||
bootstrap_server_url: Option<String>, | ||
signaling_server_url: Option<String>, | ||
config_path: String, | ||
allowed_origin: String, | ||
admin_port: u16, | ||
keystore_connection_url: String, | ||
bootstrap_server_url: Option<String>, | ||
signaling_server_url: Option<String>, | ||
config_path: String, | ||
allowed_origin: String, | ||
ice_server_urls: Option<Vec<String>>, | ||
) -> Result<String> { | ||
let mut config = std::fs::read_to_string(&PathBuf::from(config_path)) | ||
.map_err(|_| create_error("Failed to read file")) | ||
.and_then(|contents| { | ||
serde_yaml::from_str::<Value>(&contents).map_err(|_| create_error("Failed to parse YAML")) | ||
}) | ||
.and_then(|yaml| { | ||
yaml | ||
.as_mapping() | ||
.cloned() | ||
.ok_or_else(|| create_error("Expected YAML content to be a mapping")) | ||
})?; | ||
|
||
let websocket_interface = create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("websocket"))), | ||
("port", Value::Number(admin_port.into())), | ||
("allowed_origins", Value::String(allowed_origin)), | ||
]); | ||
|
||
let admin_interface = | ||
create_mapping_with_entries(vec![("driver", Value::Mapping(websocket_interface))]); | ||
|
||
insert_mapping( | ||
&mut config, | ||
"admin_interfaces", | ||
Value::Sequence(vec![Value::Mapping(admin_interface)]), | ||
); | ||
|
||
insert_mapping( | ||
&mut config, | ||
"keystore", | ||
Value::Mapping(create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("lair_server"))), | ||
("connection_url", Value::String(keystore_connection_url)), | ||
])), | ||
); | ||
|
||
let network = config | ||
.get_mut(&Value::String(String::from("network"))) | ||
.and_then(|v| v.as_mapping_mut()) | ||
.ok_or_else(|| create_error("Expected 'network' entry in the config"))?; | ||
|
||
bootstrap_server_url.map(|url| { | ||
network.insert( | ||
Value::String(String::from("bootstrap_service")), | ||
Value::String(url), | ||
let mut config = std::fs::read_to_string(&PathBuf::from(config_path)) | ||
.map_err(|_| create_error("Failed to read file")) | ||
.and_then(|contents| { | ||
serde_yaml::from_str::<Value>(&contents) | ||
.map_err(|_| create_error("Failed to parse YAML")) | ||
}) | ||
.and_then(|yaml| { | ||
yaml.as_mapping() | ||
.cloned() | ||
.ok_or_else(|| create_error("Expected YAML content to be a mapping")) | ||
})?; | ||
|
||
let websocket_interface = create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("websocket"))), | ||
("port", Value::Number(admin_port.into())), | ||
("allowed_origins", Value::String(allowed_origin)), | ||
]); | ||
|
||
let admin_interface = | ||
create_mapping_with_entries(vec![("driver", Value::Mapping(websocket_interface))]); | ||
|
||
insert_mapping( | ||
&mut config, | ||
"admin_interfaces", | ||
Value::Sequence(vec![Value::Mapping(admin_interface)]), | ||
); | ||
|
||
insert_mapping( | ||
&mut config, | ||
"keystore", | ||
Value::Mapping(create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("lair_server"))), | ||
("connection_url", Value::String(keystore_connection_url)), | ||
])), | ||
); | ||
}); | ||
|
||
signaling_server_url.map(|url| { | ||
let transport_pool = network | ||
.entry(Value::String(String::from("transport_pool"))) | ||
.or_insert_with(|| Value::Sequence(Vec::new())); | ||
if let Value::Sequence(transport_pool_seq) = transport_pool { | ||
transport_pool_seq.clear(); // Clear existing transport pool entries | ||
transport_pool_seq.push(Value::Mapping(create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("webrtc"))), | ||
("signal_url", Value::String(url)), | ||
]))); | ||
|
||
let network = config | ||
.get_mut(&Value::String(String::from("network"))) | ||
.and_then(|v| v.as_mapping_mut()) | ||
.ok_or_else(|| create_error("Expected 'network' entry in the config"))?; | ||
|
||
bootstrap_server_url.map(|url| { | ||
network.insert( | ||
Value::String(String::from("bootstrap_service")), | ||
Value::String(url), | ||
); | ||
}); | ||
|
||
let mut webrtc_config = Mapping::new(); | ||
if let Some(ice_urls) = ice_server_urls.clone() { | ||
let mut ice_servers = Sequence::new(); | ||
for url in ice_urls { | ||
let mut url_mapping = Mapping::new(); | ||
let mut url_list = Sequence::new(); | ||
url_list.push(Value::String(url)); | ||
insert_mapping(&mut url_mapping, "urls", Value::Sequence(url_list)); | ||
ice_servers.push(Value::Mapping(url_mapping)); | ||
} | ||
insert_mapping( | ||
&mut webrtc_config, | ||
"ice_servers", | ||
Value::Sequence(ice_servers), | ||
); | ||
} | ||
}); | ||
|
||
let _ = config | ||
.get(&Value::String(String::from("network"))) | ||
.and_then(|v| v.as_mapping()) | ||
.and_then(|network| network.get(&Value::String(String::from("bootstrap_service")))) | ||
.and_then(|v| v.as_str()); | ||
match (signaling_server_url.clone(), ice_server_urls.clone()) { | ||
(None, None) => (), | ||
_ => { | ||
let transport_pool = network | ||
.entry(Value::String(String::from("transport_pool"))) | ||
.or_insert_with(|| Value::Sequence(Vec::new())); | ||
|
||
if let Value::Sequence(transport_pool_seq) = transport_pool { | ||
let signaling_url = match signaling_server_url { | ||
Some(url) => Value::String(url), | ||
None => { | ||
let tpool_element = transport_pool_seq.first(); | ||
match tpool_element { | ||
Some(el) => el.get("signal_url").ok_or(napi::Error::from_reason("Conductor config did not contain a signaling server url."))?.to_owned(), | ||
None => return Err(napi::Error::from_reason("Conductor config did not contain any element in the transport_pool section")) | ||
} | ||
} | ||
}; | ||
transport_pool_seq.clear(); // Clear existing transport pool entries | ||
let mut transport_pool_mapping = create_mapping_with_entries(vec![ | ||
("type", Value::String(String::from("webrtc"))), | ||
("signal_url", signaling_url), | ||
]); | ||
if let Some(_) = ice_server_urls { | ||
insert_mapping( | ||
&mut transport_pool_mapping, | ||
"webrtc_config", | ||
Value::Mapping(webrtc_config), | ||
); | ||
} | ||
transport_pool_seq.push(Value::Mapping(transport_pool_mapping)); | ||
} | ||
} | ||
} | ||
|
||
serde_yaml::to_string(&config) | ||
.map_err(|_| create_error("Could not convert conductor config to string")) | ||
serde_yaml::to_string(&config) | ||
.map_err(|_| create_error("Could not convert conductor config to string")) | ||
} | ||
|
||
#[napi] | ||
pub fn default_conductor_config( | ||
admin_port: u16, | ||
keystore_connection_url: String, | ||
bootstrap_server_url: String, | ||
signaling_server_url: String, | ||
conductor_environment_path: String, | ||
allowed_origin: String, | ||
admin_port: u16, | ||
keystore_connection_url: String, | ||
bootstrap_server_url: String, | ||
signaling_server_url: String, | ||
conductor_environment_path: String, | ||
allowed_origin: String, | ||
ice_server_urls: Option<Vec<String>>, | ||
) -> Result<String> { | ||
let mut network_config = KitsuneP2pConfig::default(); | ||
network_config.bootstrap_service = Some(url2::url2!("{}", bootstrap_server_url)); | ||
|
||
let tuning_params = KitsuneP2pTuningParams::default(); | ||
network_config.tuning_params = std::sync::Arc::new(tuning_params); | ||
|
||
network_config.transport_pool.push(TransportConfig::WebRTC { | ||
signal_url: signaling_server_url, | ||
webrtc_config: None, | ||
}); | ||
|
||
let mut allowed_origins_map = HashSet::new(); | ||
allowed_origins_map.insert(allowed_origin); | ||
|
||
let config = ConductorConfig { | ||
data_root_path: Some(DataRootPath::from(PathBuf::from(conductor_environment_path))), | ||
dpki: None, | ||
keystore: KeystoreConfig::LairServer { | ||
connection_url: url2::url2!("{}", keystore_connection_url), | ||
}, | ||
admin_interfaces: Some(vec![AdminInterfaceConfig { | ||
driver: InterfaceDriver::Websocket { port: admin_port, allowed_origins: AllowedOrigins::Origins(allowed_origins_map) }, | ||
}]), | ||
network: network_config, | ||
db_sync_strategy: Default::default(), | ||
tracing_override: None, | ||
tuning_params: None, | ||
}; | ||
|
||
serde_yaml::to_string(&config) | ||
.map_err(|_| create_error("Failed to convert conductor config to yaml string.")) | ||
let mut network_config = KitsuneP2pConfig::default(); | ||
network_config.bootstrap_service = Some(url2::url2!("{}", bootstrap_server_url)); | ||
|
||
let tuning_params = KitsuneP2pTuningParams::default(); | ||
network_config.tuning_params = std::sync::Arc::new(tuning_params); | ||
|
||
let webrtc_config = match ice_server_urls { | ||
Some(urls) => Some(webrtc_config_from_ice_urls(urls)), | ||
None => None, | ||
}; | ||
|
||
network_config.transport_pool.push(TransportConfig::WebRTC { | ||
signal_url: signaling_server_url, | ||
webrtc_config, | ||
}); | ||
|
||
let mut allowed_origins_map = HashSet::new(); | ||
allowed_origins_map.insert(allowed_origin); | ||
|
||
let config = ConductorConfig { | ||
data_root_path: Some(DataRootPath::from(PathBuf::from( | ||
conductor_environment_path, | ||
))), | ||
dpki: None, | ||
keystore: KeystoreConfig::LairServer { | ||
connection_url: url2::url2!("{}", keystore_connection_url), | ||
}, | ||
admin_interfaces: Some(vec![AdminInterfaceConfig { | ||
driver: InterfaceDriver::Websocket { | ||
port: admin_port, | ||
allowed_origins: AllowedOrigins::Origins(allowed_origins_map), | ||
}, | ||
}]), | ||
network: network_config, | ||
db_sync_strategy: Default::default(), | ||
tracing_override: None, | ||
tuning_params: None, | ||
}; | ||
|
||
serde_yaml::to_string(&config) | ||
.map_err(|_| create_error("Failed to convert conductor config to yaml string.")) | ||
} |
Oops, something went wrong.