Merge pull request 'Extensively use rustfmt' (#11) from quality/rustfmt into main
continuous-integration/drone/push Build is passing Details
continuous-integration/drone Build is passing Details

Reviewed-on: #11
This commit is contained in:
Quentin 2021-09-20 16:06:02 +02:00
commit 4d4d453afa
13 changed files with 150 additions and 68 deletions

View File

@ -9,16 +9,16 @@ steps:
- name: code style - name: code style
image: rust:1.47 image: rust:1.47
commands: commands:
- rustup component add rustfmt - rustup toolchain install nightly-x86_64-unknown-linux-gnu
- cargo fmt --all -- --check - rustup component add rustfmt --toolchain nightly
- cargo +nightly fmt --all -- --check
# - name: code quality # - name: code quality
# image: rust:1.47 # image: rust:1.47
# commands: # commands:
# - cargo clippy -- --deny warnings # - cargo clippy -- --deny warnings
# - name: test - name: test
# image: rust:1.47 image: rust:1.47
# commands: commands:
# - cargo build --verbose --all - cargo build --verbose --all
# - cargo test --verbose --all - cargo test --verbose --all

View File

@ -1,2 +1,75 @@
unstable_features = true
array_width = 60
attr_fn_like_width = 70
binop_separator = "Front"
blank_lines_lower_bound = 0
blank_lines_upper_bound = 1
brace_style = "SameLineWhere"
chain_width = 60
color = "Auto"
combine_control_expr = true
comment_width = 80
condense_wildcard_suffixes = true
control_brace_style = "AlwaysSameLine"
disable_all_formatting = false
empty_item_single_line = true
enum_discrim_align_threshold = 0
error_on_line_overflow = true
error_on_unformatted = true
fn_args_layout = "Tall"
fn_call_width = 60
fn_single_line = true
force_explicit_abi = true
force_multiline_blocks = false
format_code_in_doc_comments = true
# format_generated_files = true
format_macro_matchers = true
format_macro_bodies = true
format_strings = true
hard_tabs = false hard_tabs = false
#hex_literal_case = "Lower"
hide_parse_errors = false
ignore = []
imports_indent = "Block"
imports_layout = "Mixed"
indent_style = "Block"
inline_attribute_width = 0
license_template_path = ""
match_arm_blocks = true
match_arm_leading_pipes = "Never"
match_block_trailing_comma = false
max_width = 100
merge_derives = true
imports_granularity = "Crate"
newline_style = "Unix"
normalize_comments = true
normalize_doc_attributes = true
overflow_delimited_expr = false
remove_nested_parens = true
reorder_impl_items = true
reorder_imports = true
group_imports = "StdExternalCrate"
reorder_modules = true
report_fixme = "Unnumbered"
report_todo = "Unnumbered"
required_version = "1.4.37"
skip_children = false
single_line_if_else_max_width = 50
space_after_colon = true
space_before_colon = false
#space_around_ranges = false
struct_field_align_threshold = 0
struct_lit_single_line = true
struct_lit_width = 18
struct_variant_width = 35
tab_spaces = 2 tab_spaces = 2
trailing_comma = "Vertical"
trailing_semicolon = false
type_punctuation_density = "Wide"
use_field_init_shorthand = false
use_small_heuristics = "Off"
use_try_shorthand = true
version = "Two"
where_single_line = true
wrap_comments = true

View File

@ -8,12 +8,13 @@
#### Installing rustfmt #### Installing rustfmt
You can run `rustfmt` with Rust 1.24 and above. You must install a very recent version of `rustfmt` through rust nightly
To install: To install:
``` ```
rustup component add rustfmt rustup toolchain install nightly-x86_64-unknown-linux-gnu
rustup component add rustfmt --toolchain nightly
``` ```
#### Usage #### Usage
@ -21,14 +22,24 @@ rustup component add rustfmt
To run on Diplonat, launch the following in the root directory: To run on Diplonat, launch the following in the root directory:
``` ```
cargo fmt --all cargo +nightly fmt
``` ```
This will format the whole repository using the settigs defined in [`.rustfmt.toml`](./.rustfmt.toml): soft tabs of 2 spaces. This will format the whole repository using the settigs defined in [`.rustfmt.toml`](./.rustfmt.toml).
#### Auto-format code #### Auto-format code
You can automate formatting in a number of ways: You can automate formatting in a number of ways:
* [Setup your IDE to use `rustfmt`](https://github.com/rust-lang/rustfmt#running-rustfmt-from-your-editor). [Setup your IDE to use `rustfmt`](https://github.com/rust-lang/rustfmt#running-rustfmt-from-your-editor).
* Setup a git hook to run `rustfmt` before each commit.
Setup a git hook to run `rustfmt` before each commit:
```bash
cat <<EOF > .git/hooks/pre-commit
#!/bin/bash
cargo +nightly fmt
EOF
chmod +x .git/hooks/pre-commit
```

View File

@ -62,9 +62,7 @@ impl ConfigOpts {
// Currently only used in tests // Currently only used in tests
#[allow(dead_code)] #[allow(dead_code)]
pub fn from_iter<Iter: Clone>(iter: Iter) -> Result<RuntimeConfig> pub fn from_iter<Iter: Clone>(iter: Iter) -> Result<RuntimeConfig>
where where Iter: IntoIterator<Item = (String, String)> {
Iter: IntoIterator<Item = (String, String)>,
{
let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_iter(iter.clone())?; let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_iter(iter.clone())?;
let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_iter(iter.clone())?; let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_iter(iter.clone())?;
let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_iter(iter.clone())?; let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_iter(iter.clone())?;

View File

@ -1,5 +1,4 @@
use std::collections::HashMap; use std::{collections::HashMap, time::Duration};
use std::time::Duration;
use crate::config::*; use crate::config::*;

View File

@ -6,8 +6,8 @@ use crate::config::{ConfigOpts, ConfigOptsAcme, ConfigOptsBase, ConfigOptsConsul
// This code is inspired by the Trunk crate (https://github.com/thedodd/trunk) // This code is inspired by the Trunk crate (https://github.com/thedodd/trunk)
// In this file, we take ConfigOpts and transform them into ready-to-use RuntimeConfig. // In this file, we take ConfigOpts and transform them into ready-to-use
// We apply default values and business logic. // RuntimeConfig. We apply default values and business logic.
#[derive(Debug)] #[derive(Debug)]
pub struct RuntimeConfigAcme { pub struct RuntimeConfigAcme {
@ -59,12 +59,11 @@ impl RuntimeConfig {
impl RuntimeConfigAcme { impl RuntimeConfigAcme {
pub fn new(opts: ConfigOptsAcme) -> Result<Option<Self>> { pub fn new(opts: ConfigOptsAcme) -> Result<Option<Self>> {
if !opts.enable { if !opts.enable {
return Ok(None); return Ok(None)
} }
let email = opts.email.expect( let email = opts.email.expect(
"'DIPLONAT_ACME_EMAIL' environment variable is required \ "'DIPLONAT_ACME_EMAIL' environment variable is required if 'DIPLONAT_ACME_ENABLE' == 'true'",
if 'DIPLONAT_ACME_ENABLE' == 'true'",
); );
Ok(Some(Self { email })) Ok(Some(Self { email }))
@ -105,9 +104,11 @@ impl RuntimeConfigIgd {
if refresh_time.as_secs() * 2 > expiration_time.as_secs() { if refresh_time.as_secs() * 2 > expiration_time.as_secs() {
return Err(anyhow!( return Err(anyhow!(
"IGD expiration time (currently: {}s) must be at least twice bigger than refresh time (currently: {}s)", "IGD expiration time (currently: {}s) must be at least twice bigger than refresh time \
expiration_time.as_secs(), (currently: {}s)",
refresh_time.as_secs())); expiration_time.as_secs(),
refresh_time.as_secs()
))
} }
Ok(Self { Ok(Self {

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct ServiceEntry { pub struct ServiceEntry {
@ -24,12 +25,10 @@ impl Consul {
client: reqwest::Client::new(), client: reqwest::Client::new(),
url: url.to_string(), url: url.to_string(),
idx: None, idx: None,
}; }
} }
pub fn watch_node_reset(&mut self) -> () { pub fn watch_node_reset(&mut self) -> () { self.idx = None; }
self.idx = None;
}
pub async fn watch_node(&mut self, host: &str) -> Result<CatalogNode> { pub async fn watch_node(&mut self, host: &str) -> Result<CatalogNode> {
let url = match self.idx { let url = match self.idx {
@ -44,6 +43,6 @@ impl Consul {
}; };
let resp: CatalogNode = http.json().await?; let resp: CatalogNode = http.json().await?;
return Ok(resp); return Ok(resp)
} }
} }

View File

@ -1,14 +1,12 @@
use crate::consul; use std::{cmp, collections::HashSet, time::Duration};
use crate::messages;
use anyhow::Result; use anyhow::Result;
use log::*; use log::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_lexpr::{error, from_str}; use serde_lexpr::{error, from_str};
use std::cmp; use tokio::{sync::watch, time::delay_for};
use std::collections::HashSet;
use std::time::Duration; use crate::{consul, messages};
use tokio::sync::watch;
use tokio::time::delay_for;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub enum DiplonatParameter { pub enum DiplonatParameter {
@ -32,11 +30,12 @@ pub struct ConsulActor {
fn retry_to_time(retries: u32, max_time: Duration) -> Duration { fn retry_to_time(retries: u32, max_time: Duration) -> Duration {
// 1.2^x seems to be a good value to exponentially increase time at a good pace // 1.2^x seems to be a good value to exponentially increase time at a good pace
// eg. 1.2^32 = 341 seconds ~= 5 minutes - ie. after 32 retries we wait 5 minutes // eg. 1.2^32 = 341 seconds ~= 5 minutes - ie. after 32 retries we wait 5
// minutes
return Duration::from_secs(cmp::min( return Duration::from_secs(cmp::min(
max_time.as_secs(), max_time.as_secs(),
1.2f64.powf(retries as f64) as u64, 1.2f64.powf(retries as f64) as u64,
)); ))
} }
fn to_parameters(catalog: &consul::CatalogNode) -> Vec<DiplonatConsul> { fn to_parameters(catalog: &consul::CatalogNode) -> Vec<DiplonatConsul> {
@ -52,7 +51,7 @@ fn to_parameters(catalog: &consul::CatalogNode) -> Vec<DiplonatConsul> {
} }
} }
return r; return r
} }
fn to_open_ports(params: &Vec<DiplonatConsul>) -> messages::PublicExposedPorts { fn to_open_ports(params: &Vec<DiplonatConsul>) -> messages::PublicExposedPorts {
@ -71,7 +70,7 @@ fn to_open_ports(params: &Vec<DiplonatConsul>) -> messages::PublicExposedPorts {
} }
} }
return op; return op
} }
impl ConsulActor { impl ConsulActor {
@ -87,7 +86,7 @@ impl ConsulActor {
tx_open_ports: tx, tx_open_ports: tx,
node: node.to_string(), node: node.to_string(),
retries: 0, retries: 0,
}; }
} }
pub async fn listen(&mut self) -> Result<()> { pub async fn listen(&mut self) -> Result<()> {
@ -104,7 +103,7 @@ impl ConsulActor {
e e
); );
delay_for(will_retry_in).await; delay_for(will_retry_in).await;
continue; continue
} }
}; };
self.retries = 0; self.retries = 0;

View File

@ -1,10 +1,9 @@
use anyhow::Result; use anyhow::Result;
use tokio::try_join; use tokio::try_join;
use crate::config::ConfigOpts; use crate::{
use crate::consul_actor::ConsulActor; config::ConfigOpts, consul_actor::ConsulActor, fw_actor::FirewallActor, igd_actor::IgdActor,
use crate::fw_actor::FirewallActor; };
use crate::igd_actor::IgdActor;
pub struct Diplonat { pub struct Diplonat {
consul: ConsulActor, consul: ConsulActor,
@ -35,7 +34,7 @@ impl Diplonat {
firewall: fw, firewall: fw,
}; };
return Ok(ctx); return Ok(ctx)
} }
pub async fn listen(&mut self) -> Result<()> { pub async fn listen(&mut self) -> Result<()> {
@ -45,6 +44,6 @@ impl Diplonat {
self.firewall.listen() self.firewall.listen()
)?; )?;
return Ok(()); return Ok(())
} }
} }

View File

@ -1,9 +1,11 @@
use crate::messages; use std::collections::HashSet;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use iptables; use iptables;
use log::*; use log::*;
use regex::Regex; use regex::Regex;
use std::collections::HashSet;
use crate::messages;
pub fn setup(ipt: &iptables::IPTables) -> Result<()> { pub fn setup(ipt: &iptables::IPTables) -> Result<()> {
// ensure we start from a clean state without any rule already set // ensure we start from a clean state without any rule already set

View File

@ -1,4 +1,7 @@
use std::collections::HashSet;
use anyhow::Result; use anyhow::Result;
use iptables;
use log::*; use log::*;
use tokio::{ use tokio::{
select, select,
@ -6,10 +9,7 @@ use tokio::{
time::{self, Duration}, time::{self, Duration},
}; };
use crate::fw; use crate::{fw, messages};
use crate::messages;
use iptables;
use std::collections::HashSet;
pub struct FirewallActor { pub struct FirewallActor {
pub ipt: iptables::IPTables, pub ipt: iptables::IPTables,
@ -32,7 +32,7 @@ impl FirewallActor {
fw::setup(&ctx.ipt)?; fw::setup(&ctx.ipt)?;
return Ok(ctx); return Ok(ctx)
} }
pub async fn listen(&mut self) -> Result<()> { pub async fn listen(&mut self) -> Result<()> {
@ -81,6 +81,6 @@ impl FirewallActor {
fw::open_ports(&self.ipt, ports_to_open)?; fw::open_ports(&self.ipt, ports_to_open)?;
return Ok(()); return Ok(())
} }
} }

View File

@ -1,15 +1,16 @@
use crate::messages;
use anyhow::{Context, Result};
use igd::aio::*;
use igd::PortMappingProtocol;
use log::*;
use std::net::SocketAddrV4; use std::net::SocketAddrV4;
use anyhow::{Context, Result};
use igd::{aio::*, PortMappingProtocol};
use log::*;
use tokio::{ use tokio::{
select, select,
sync::watch, sync::watch,
time::{self, Duration}, time::{self, Duration},
}; };
use crate::messages;
pub struct IgdActor { pub struct IgdActor {
last_ports: messages::PublicExposedPorts, last_ports: messages::PublicExposedPorts,
rx_ports: watch::Receiver<messages::PublicExposedPorts>, rx_ports: watch::Receiver<messages::PublicExposedPorts>,
@ -40,7 +41,7 @@ impl IgdActor {
last_ports: messages::PublicExposedPorts::new(), last_ports: messages::PublicExposedPorts::new(),
}; };
return Ok(ctx); return Ok(ctx)
} }
pub async fn listen(&mut self) -> Result<()> { pub async fn listen(&mut self) -> Result<()> {
@ -92,6 +93,6 @@ impl IgdActor {
} }
} }
return Ok(()); return Ok(())
} }
} }

View File

@ -11,6 +11,6 @@ impl PublicExposedPorts {
return Self { return Self {
tcp_ports: HashSet::new(), tcp_ports: HashSet::new(),
udp_ports: HashSet::new(), udp_ports: HashSet::new(),
}; }
} }
} }