Skip to content

Commit

Permalink
Issue-95: Netbird setup key expiration no longer hard coded, moved in…
Browse files Browse the repository at this point in the history
…to carl.toml.

Co-authored-by: Anna Völker <[email protected]>
Co-authored-by: Matthias Twardawski <[email protected]>
  • Loading branch information
2 people authored and mbfm committed Aug 30, 2024
1 parent d27e2a2 commit 4ea1af6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 91 deletions.
1 change: 1 addition & 0 deletions opendut-carl/carl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ auth.type = ""
auth.secret = ""
timeout.ms = 10000
retries = 5
setup.key.expiration.ms = 86400000

[logging]
stdout = true
Expand Down
118 changes: 39 additions & 79 deletions opendut-carl/src/vpn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use std::time::Duration;

use anyhow::{anyhow, bail};
use config::Config;
use serde::{Deserialize, Serialize};
use serde::de::IntoDeserializer;
use tracing::debug;
use url::Url;

Expand All @@ -20,36 +18,59 @@ pub enum Vpn {

pub fn create(settings: &Config) -> anyhow::Result<Vpn> {

let vpn = settings.get::<VpnConfig>("vpn")?;
let vpn = settings.get::<bool>("vpn.enabled")?;

if vpn.enabled {
match vpn.kind {
None => unknown_enum_variant(settings, "vpn.kind"),
Some(VpnKind::Netbird) => {
let netbird_config = settings.get::<VpnNetbirdConfig>("vpn.netbird")?;
let base_url = netbird_config.url
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.base.url"))?;
let ca = netbird_config.ca
if vpn {
let vpn_kind_key = "vpn.kind";
let vpn_kind = settings.get::<String>(vpn_kind_key)?;

match vpn_kind.as_ref() {
"netbird" => {
let base_url = settings.get::<Option<Url>>("vpn.netbird.url")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.url"))?;

let ca = settings.get::<Option<PathBuf>>("vpn.netbird.ca")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.ca"))?;
let auth_secret = netbird_config.auth.secret

let auth_secret = settings.get::<Option<String>>("vpn.netbird.auth.secret")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.auth.secret"))?;
let auth_token = match netbird_config.auth.r#type {
Some(AuthenticationType::PersonalAccessToken) => NetbirdToken::new_personal_access(auth_secret),
Some(AuthenticationType::BearerToken) => unimplemented!("Using a bearer token is not yet supported."),
None => return unknown_enum_variant(settings, "vpn.netbird.auth.type"),

let vpn_netbird_auth_type = "vpn.netbird.auth.type";
let auth_type = settings.get::<Option<String>>(vpn_netbird_auth_type)?;

let auth_token = match auth_type {
Some(auth_type) => match auth_type.as_ref() {
"personal-access-token" => NetbirdToken::new_personal_access(auth_secret),
"bearer-token" => unimplemented!("Using a bearer token is not yet supported."),
_ => return Err(anyhow!("Invalid configuration parameter for '{vpn_netbird_auth_type}', allowed values are 'bearer-token' and 'personal-access-token'.")),
}
None => return unknown_enum_variant(settings, vpn_netbird_auth_type)
};

let timeout_ms = settings.get::<Option<u64>>("vpn.netbird.timeout.ms")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.timeout.ms"))?;

let retries = settings.get::<Option<u32>>("vpn.netbird.retries")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.retries"))?;

let setup_key_expiration_ms = settings.get::<Option<u64>>("vpn.netbird.setup.key.expiration.ms")?
.ok_or_else(|| anyhow!("No configuration found for: vpn.netbird.setup.key.expiration.ms"))?;

debug!("Try to parse VPN configuration.");
let vpn_client = NetbirdManagementClient::create(
NetbirdManagementClientConfiguration {
management_url: base_url,
authentication_token: Some(auth_token),
ca: Some(ca),
timeout: Duration::from_millis(netbird_config.timeout.ms),
retries: netbird_config.retries,
timeout: Duration::from_millis(timeout_ms),
retries,
setup_key_expiration: Duration::from_millis(setup_key_expiration_ms),
}
)?;
Ok(Vpn::Enabled { vpn_client: Arc::new(vpn_client) })
}
"" => unknown_enum_variant(settings, vpn_kind_key),
other => Err(anyhow!("Invalid configuration parameter '{other}' for key '{vpn_kind_key}', allowed value is 'netbird'.")),
}
} else {
Ok(Vpn::Disabled)
Expand All @@ -64,64 +85,3 @@ fn unknown_enum_variant(settings: &Config, key: &str) -> anyhow::Result<Vpn> {
bail!("Unknown {key}: {value}")
}
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
struct VpnConfig {
enabled: bool,
#[serde(deserialize_with = "empty_string_as_none")]
kind: Option<VpnKind>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
enum VpnKind {
Netbird,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
struct VpnNetbirdConfig {
#[serde(deserialize_with = "empty_string_as_none")]
url: Option<Url>,
#[serde(deserialize_with = "empty_string_as_none")]
ca: Option<PathBuf>,
auth: AuthConfig,
timeout: Timeout,
retries: u32,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
struct Timeout {
ms: u64,
}


#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
struct AuthConfig {
#[serde(deserialize_with = "empty_string_as_none")]
r#type: Option<AuthenticationType>,
#[serde(deserialize_with = "empty_string_as_none")]
secret: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all="kebab-case")]
enum AuthenticationType {
PersonalAccessToken,
BearerToken,
}

fn empty_string_as_none<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: serde::Deserialize<'de>,
{
let maybe_string = Option::<String>::deserialize(deserializer)?;
match maybe_string.as_deref() {
None | Some("") => Ok(None),
Some(string) => T::deserialize(string.into_deserializer()).map(Some)
}
}
7 changes: 4 additions & 3 deletions opendut-vpn/opendut-vpn-netbird/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ pub trait Client {

pub struct DefaultClient {
netbird_url: Url,
setup_key_expiration: Duration,
requester: Box<dyn RequestHandler + Send + Sync>,
}

impl DefaultClient {

const SETUP_KEY_EXPIRY_DURATION: Duration = Duration::from_secs(24 * 60 * 60);
const APPLICATION_JSON: &'static str = "application/json";

pub fn create(
Expand All @@ -48,6 +47,7 @@ impl DefaultClient {
requester: Option<Box<dyn RequestHandler + Send + Sync>>,
timeout: Duration,
retries: u32,
setup_key_expiration: Duration,
) -> Result<Self, CreateClientError>
{
let headers = {
Expand Down Expand Up @@ -86,6 +86,7 @@ impl DefaultClient {

Ok(Self {
netbird_url,
setup_key_expiration,
requester,
})
}
Expand Down Expand Up @@ -273,7 +274,7 @@ impl Client for DefaultClient {
CreateSetupKey {
name: netbird::setup_key_name_format(peer_id),
r#type: netbird::SetupKeyType::Reusable,
expires_in: DefaultClient::SETUP_KEY_EXPIRY_DURATION.as_secs(),
expires_in: self.setup_key_expiration.as_secs(),
revoked: false,
auto_groups: vec![
peer_group.id.0
Expand Down
13 changes: 7 additions & 6 deletions opendut-vpn/opendut-vpn-netbird/src/client/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use opendut_types::cluster::ClusterId;
use super::*;
const RETRIES: u32 = 5;
const TIMEOUT: Duration = Duration::from_secs(10000);
const SETUP_KEY_EXPIRATION: Duration = Duration::from_millis(86400000);

#[rstest]
#[tokio::test]
Expand All @@ -30,7 +31,7 @@ async fn delete_peer(fixture: Fixture) -> anyhow::Result<()> {
.unwrap()))
});

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let result = client.delete_netbird_peer(&netbird::PeerId::from("ah8cca16lmn67acg5s11")).await;

Expand Down Expand Up @@ -74,7 +75,7 @@ async fn create_group(fixture: Fixture) -> anyhow::Result<()> {
Ok(Response::from(response))
});

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let result = client.create_netbird_group(
fixture.cluster_id().into(),
Expand Down Expand Up @@ -126,7 +127,7 @@ async fn find_group(fixture: Fixture) -> anyhow::Result<()> {
Ok(Response::from(response))
});

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let result = client.get_netbird_group(&fixture.peer_netbird_group_name).await;

Expand Down Expand Up @@ -160,7 +161,7 @@ async fn delete_group(fixture: Fixture) -> anyhow::Result<()> {
}
);

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let result = client.delete_netbird_group(&netbird::GroupId::from("aax77acflma44h075aa3")).await;

Expand Down Expand Up @@ -239,7 +240,7 @@ async fn create_a_setup_key(fixture: Fixture) -> anyhow::Result<()> {
}
});

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let result = client.generate_netbird_setup_key(fixture.peer_id()).await?;

Expand Down Expand Up @@ -308,7 +309,7 @@ async fn create_access_control_rule(fixture: Fixture) -> anyhow::Result<()> {
Ok(Response::from(response))
});

let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES)?;
let client = DefaultClient::create(fixture.base_url(), None, None, Some(Box::new(requester)), TIMEOUT, RETRIES, SETUP_KEY_EXPIRATION)?;

let group = netbird::Group {
id: fixture.netbird_group_id(),
Expand Down
8 changes: 5 additions & 3 deletions opendut-vpn/opendut-vpn-netbird/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ pub struct NetbirdManagementClientConfiguration {
pub authentication_token: Option<NetbirdToken>,
pub ca: Option<PathBuf>,
pub timeout: Duration,
pub retries: u32
pub retries: u32,
pub setup_key_expiration: Duration,
}

pub struct NetbirdManagementClient {
Expand Down Expand Up @@ -57,11 +58,12 @@ impl NetbirdManagementClient {
configuration.authentication_token,
None,
configuration.timeout,
configuration.retries
configuration.retries,
configuration.setup_key_expiration,
)?);
Ok(Self {
management_url,
inner
inner,
})
}
}
Expand Down

0 comments on commit 4ea1af6

Please sign in to comment.