Skip to main content

pdns_client/client/
servers.rs

1//! impl the server related PDNS API functions
2//! source: <https://doc.powerdns.com/authoritative/http-api/server.html>
3
4use super::error::PdnsAPIError;
5use super::result::Result;
6
7use serde::Deserialize;
8use std::fmt;
9
10// src: https://github.com/zhiburt/tabled#set-column-order
11use tabled::Tabled;
12
13/// The server information returned by pdns API.
14/// Note, crucially, this does not contain any information about the client (and thus the pdns webserver) used to retrieve this information.
15/// As a result, users may want to ensure that servers being compared, are retrieved from the same client/pdns webserver.
16#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Tabled)]
17pub struct Server {
18    /// server id
19    #[tabled(order = 0)]
20    pub id: String,
21
22    /// daemon type
23    #[tabled(order = 1)]
24    pub daemon_type: String,
25
26    /// server version
27    #[tabled(order = 2)]
28    pub version: String,
29
30    #[serde(rename = "type")] // type is a keyword in rust and thus unusable as field name
31    /// server type
32    #[tabled(skip)]
33    pub server_type: String,
34
35    /// server url
36    #[tabled(skip)]
37    pub url: String,
38
39    /// server's config url
40    #[tabled(skip)]
41    pub config_url: String,
42
43    /// server's zone url
44    #[tabled(skip)]
45    pub zones_url: String,
46
47    /// server's automprimaries url
48    #[tabled(skip)]
49    pub autoprimaries: String,
50}
51
52impl fmt::Display for Server {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        write!(
55            f,
56            "pdns server with id={}, type={}, daemon_type={}",
57            self.id, self.server_type, self.daemon_type
58        )
59    }
60}
61
62impl super::Client {
63    /// list the servers
64    ///
65    /// # Errors
66    /// - [`super::Error::Url`] if the api endpoint url could not be formed
67    /// - [`super::Error::Http`] if errors in making request
68    /// - [`super::Error::Http`] if errors in decoding response JSON on a successful request
69    /// - [`super::Error::APIError`] if api returned an error (not 200 OK status)
70    pub fn list_servers(&self) -> Result<Vec<Server>> {
71        let url = self.base_url.join("servers")?;
72
73        let resp = self.client.get(url).send()?;
74        let status = resp.status();
75
76        // status code denotes error
77        if status != http::StatusCode::OK {
78            // here since resp.json it not returned directly, the compiler
79            // cant figure out the type to deserialize it into and thus we must specify it
80            // the return type does, at least, signal to the compiler what type into should convert to
81            return Err(resp.json::<PdnsAPIError>()?.into());
82        }
83
84        Ok(resp.json()?) // fn return type specifies the type to deserialize into
85    }
86
87    /// lists information on a specific server
88    ///
89    /// # Errors
90    /// - [`super::Error::Url`] if the api endpoint url could not be formed
91    /// - [`super::Error::Http`] if errors in making request
92    /// - [`super::Error::Http`] if errors in decoding response JSON on a successful request
93    /// - [`super::Error::APIError`] if api returned an error (not 200 OK status)
94    pub fn list_server(&self, server_id: &str) -> Result<Server> {
95        let url = self.base_url.join(&format!("servers/{server_id}"))?;
96
97        let resp = self.client.get(url).send()?;
98        let status = resp.status();
99
100        // status code denotes error
101        if status != http::StatusCode::OK {
102            // here since resp.json it not returned directly, the compiler
103            // cant figure out the type to deserialize it into and thus we must specify it
104            // the return type does, at least, signal to the compiler what type into should convert to
105            return Err(resp.json::<PdnsAPIError>()?.into());
106        }
107
108        Ok(resp.json()?) // fn return type specifies the type to deserialize into
109    }
110}