openvpn3_rs/helpers/
configuration.rs

1//! Provides an interface to communicate with the OpenVPN 3 configuration D-Bus API.
2
3use super::Session;
4
5use crate::{ConfigurationNodeProxy, Result, SessionsProxy};
6
7use zbus::{
8    zvariant::{OwnedObjectPath, OwnedValue},
9    CacheProperties, Connection,
10};
11
12/// OpenVPN 3 Configuration
13#[derive(Clone, Debug)]
14pub struct Configuration<'a> {
15    pub(crate) connection: Connection,
16    pub(crate) path: OwnedObjectPath,
17    pub(crate) proxy: ConfigurationNodeProxy<'a>,
18    pub(crate) sessions_proxy: SessionsProxy<'a>,
19}
20
21impl<'a> Configuration<'a> {
22    const DBUS_INTERFACE: &'static str = "net.openvpn.v3.configuration";
23
24    /// Constructs a new [Configuration] that represents a single OpenVPN 3 VPN configuration profile through the D-Bus API.
25    ///
26    /// # Arguments
27    ///
28    /// * `connection` - D-Bus [Connection] instance.
29    /// * `path` - D-Bus [OwnedObjectPath] to the configuration profile.
30    pub(crate) async fn new(
31        connection: Connection,
32        path: OwnedObjectPath,
33    ) -> Result<Configuration<'a>> {
34        let sessions_proxy = SessionsProxy::new(&connection).await?;
35        let proxy = ConfigurationNodeProxy::builder(&connection)
36            .destination(Self::DBUS_INTERFACE)?
37            .path(path.clone())?
38            .cache_properties(CacheProperties::No)
39            .build()
40            .await?;
41
42        Ok(Self {
43            connection,
44            path,
45            proxy,
46            sessions_proxy,
47        })
48    }
49
50    /// Start a new VPN backend client process for this VPN configuration profile.
51    pub async fn new_tunnel<'c>(&self) -> Result<Session<'c>> {
52        let proxy = self.sessions_proxy.new_tunnel(&self.path).await?;
53        Ok(Session::new(
54            self.connection.clone(),
55            OwnedObjectPath::from(proxy.path().clone()),
56        )
57        .await?)
58    }
59
60    /// Fetch the configuration as a string blob.
61    pub async fn fetch(&'a self) -> Result<String> {
62        Ok(self.proxy.fetch().await?)
63    }
64
65    /// Fetch the configuration as a JSON value.
66    pub async fn json(&'a self) -> Result<serde_json::Value> {
67        Ok(serde_json::from_str(
68            self.proxy.fetch_json().await?.as_str(),
69        )?)
70    }
71
72    /// Removes this VPN configuration profile.
73    pub async fn remove(&'a self) -> Result<()> {
74        Ok(self.proxy.remove().await?)
75    }
76
77    /// Get a property value from the underlying D-Bus proxy.
78    pub async fn get_property<T>(&'a self, property_name: &str) -> Result<T>
79    where
80        T: TryFrom<OwnedValue>,
81        T::Error: Into<zbus::Error>,
82    {
83        Ok(self.proxy.get_property(property_name).await?)
84    }
85}