feat(conf): impl command configure
This commit is contained in:
parent
bbecb1a1cc
commit
787602a93c
2 changed files with 161 additions and 1 deletions
|
@ -11,7 +11,10 @@ edition = "2018"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
duniter-core = { git = "https://git.duniter.org/nodes/rust/duniter-core" }
|
||||
read_input = "0.8"
|
||||
serde = { version = "1.0.105", features = ["derive"] }
|
||||
structopt = "0.3"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
|
|
159
conf/src/lib.rs
159
conf/src/lib.rs
|
@ -13,11 +13,14 @@
|
|||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use duniter_core::module_cli::anyhow;
|
||||
use read_input::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
||||
vec,
|
||||
};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct GvaConf {
|
||||
|
@ -96,3 +99,157 @@ impl GvaConf {
|
|||
.unwrap_or_else(|| self.subscriptions_path.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub struct GvaCli {}
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub struct GvaCliConfigure {}
|
||||
|
||||
impl duniter_core::module_cli::DuniterModuleCli for GvaCli {
|
||||
const MODULE_NAME: &'static str = "gva";
|
||||
|
||||
type Conf = GvaConf;
|
||||
|
||||
type ConfigureOpt = GvaCliConfigure;
|
||||
|
||||
type Opt = Self;
|
||||
|
||||
fn configure(mut conf: Self::Conf, _: Self::ConfigureOpt) -> Self::Conf {
|
||||
// Enable GVA API?
|
||||
let res = input().msg("Enable GVA API? [Y/n]").default('Y').get();
|
||||
conf.enabled = res != 'n';
|
||||
|
||||
if conf.enabled {
|
||||
// ip4
|
||||
conf.ip4 = input()
|
||||
.msg(format!("Listen to ip v4 ? [{}]", conf.ip4))
|
||||
.default(conf.ip4)
|
||||
.get();
|
||||
// ip6
|
||||
let res = input().msg("Listen to ip v6? [Y/n]").default('Y').get();
|
||||
if res != 'n' {
|
||||
let proposed_ip6 = conf.ip6.unwrap_or(Ipv6Addr::UNSPECIFIED);
|
||||
conf.ip6 = Some(
|
||||
input()
|
||||
.msg(format!("Enter ip v6: [{}]", proposed_ip6))
|
||||
.default(proposed_ip6)
|
||||
.get(),
|
||||
);
|
||||
} else {
|
||||
conf.ip6 = None;
|
||||
}
|
||||
// port
|
||||
conf.port = input()
|
||||
.msg(format!("Listen to port ? [{}]", conf.port))
|
||||
.default(conf.port)
|
||||
.get();
|
||||
// path
|
||||
conf.path = input()
|
||||
.msg(format!("Path ? [{}]", conf.path))
|
||||
.default(conf.path)
|
||||
.get();
|
||||
// subscriptionsPath
|
||||
conf.subscriptions_path = input()
|
||||
.msg(format!(
|
||||
"Subscriptions path ? [{}]",
|
||||
conf.subscriptions_path
|
||||
))
|
||||
.default(conf.subscriptions_path)
|
||||
.get();
|
||||
// remoteHost
|
||||
if let Some(ref remote_host) = conf.remote_host {
|
||||
let new_remote_host = input()
|
||||
.msg(format!("Remote host ? [{}]", remote_host))
|
||||
.default(remote_host.to_owned())
|
||||
.get();
|
||||
if !new_remote_host.is_empty() {
|
||||
conf.remote_host = Some(new_remote_host);
|
||||
}
|
||||
} else {
|
||||
let new_remote_host: String = input().msg("Remote host ? ").get();
|
||||
if !new_remote_host.is_empty() {
|
||||
conf.remote_host = Some(new_remote_host);
|
||||
}
|
||||
}
|
||||
// remotePort
|
||||
let res = input()
|
||||
.msg("Define a remote port? [y/N]")
|
||||
.default('N')
|
||||
.get();
|
||||
if res == 'y' || res == 'Y' {
|
||||
let default = conf.remote_port.unwrap_or(443);
|
||||
conf.remote_port = Some(
|
||||
input()
|
||||
.msg(format!("Remote port ? [{}]", default))
|
||||
.default(default)
|
||||
.get(),
|
||||
);
|
||||
} else {
|
||||
conf.remote_port = None;
|
||||
}
|
||||
// remotePath
|
||||
let res = input()
|
||||
.msg("Define a remote path? [y/N]")
|
||||
.default('N')
|
||||
.get();
|
||||
if res == 'y' || res == 'Y' {
|
||||
conf.remote_path = Some(input().msg("Enter remote path:").get());
|
||||
} else {
|
||||
conf.remote_path = None;
|
||||
}
|
||||
// remoteSubscriptionsPath
|
||||
let res = input()
|
||||
.msg("Define a remote subscriptions path? [y/N]")
|
||||
.default('N')
|
||||
.get();
|
||||
if res == 'y' || res == 'Y' {
|
||||
conf.remote_subscriptions_path =
|
||||
Some(input().msg("Enter remote subscriptions path:").get());
|
||||
} else {
|
||||
conf.remote_subscriptions_path = None;
|
||||
}
|
||||
// whitelist
|
||||
let mut whitelist: HashSet<_> = conf.whitelist.iter().copied().collect();
|
||||
let res = input().msg("Update whitelist? [y/N]").default('N').get();
|
||||
if res == 'y' || res == 'Y' {
|
||||
loop {
|
||||
println!("1. See whitelist content.");
|
||||
println!("2. Add an IP to the whitelist.");
|
||||
println!("3. Removing an IP from the whitelist.");
|
||||
println!("4. Quit.");
|
||||
match input().msg("Choose an action: ").default(1).get() {
|
||||
2usize => {
|
||||
whitelist.insert(input().msg("Enter a new IP address: ").get());
|
||||
}
|
||||
3 => {
|
||||
whitelist.remove(
|
||||
&input().msg("Indicate the IP address to be deleted: ").get(),
|
||||
);
|
||||
}
|
||||
4 => break,
|
||||
_ => {
|
||||
println!("--------------------------------");
|
||||
println!("Whitelist content ({} IPs):", whitelist.len());
|
||||
whitelist.iter().for_each(|ip| println!("{}", ip));
|
||||
println!("--------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
conf.whitelist = whitelist.iter().copied().collect();
|
||||
}
|
||||
|
||||
println!("Configuration successfully updated.");
|
||||
|
||||
conf
|
||||
}
|
||||
|
||||
fn command(
|
||||
_conf: Self::Conf,
|
||||
_opt: Self::Opt,
|
||||
_data_path: std::path::PathBuf,
|
||||
) -> anyhow::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue