diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1703900 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "datacenter" + ] +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 0d849ff..259a2a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,31 +10,35 @@ keywords = ["Consul", "API", "Client", "Hashicorp"] edition = "2018" [workspace] -members = [ - "consulrs_derive", -] +members = ["consulrs_derive"] [dependencies] -async-trait = "0.1.51" -base64 = "0.13.0" +async-trait = "0.1.80" +base64 = "0.22.1" consulrs_derive = { version = "0.1.0", path = "consulrs_derive" } -derive_builder = "0.10.2" -http = "0.2.5" -reqwest = { version = "0.11.4", default-features = false, features = ["rustls-tls"] } -rustify = "0.5.2" -rustify_derive = "0.5.2" -serde = "1.0.130" -serde_json = "1.0.66" -serde_with = "1.10.0" -thiserror = "1.0.29" -tracing = "0.1.28" +derive_builder = "0.20.0" +http = "1.1.0" +reqwest = { version = "0.12.4", default-features = false, features = [ + "rustls-tls", +] } +rustify = "0.6.0" +rustify_derive = "0.5.3" +serde = "1.0.203" +serde_json = "1.0.117" +serde_with = "3.9.0" +thiserror = "1.0.59" +tracing = "0.1.40" url = "2.2.2" [dev-dependencies] -dockertest-server = { version = "0.1.4", features=["hashi"] } -env_logger = "0.9.0" +dockertest-server = { version = "0.1.4", features = ["hashi"] } +env_logger = "0.11.3" +hyper = "1.4.1" futures = "0.3.17" -test-log = { version = "0.2.8", features = ["trace"] } -tokio = { version = "1.12.0", features = ["full"] } -tokio-test = "0.4.2" -tracing-subscriber = {version = "0.2.17", default-features = false, features = ["env-filter", "fmt"]} +test-log = { version = "0.2.16", features = ["trace"] } +tokio = { version = "1.38.0", features = ["full"] } +tokio-test = "0.4.4" +tracing-subscriber = { version = "0.3.18", default-features = false, features = [ + "env-filter", + "fmt", +] } diff --git a/consulrs_derive/Cargo.toml b/consulrs_derive/Cargo.toml index 51024ab..20e8880 100644 --- a/consulrs_derive/Cargo.toml +++ b/consulrs_derive/Cargo.toml @@ -14,6 +14,6 @@ proc-macro = true [dependencies] syn = "1.0" -quote = "1.0" +quote = "1.0.36" synstructure = "0.12.5" -proc-macro2 = "1.0.28" +proc-macro2 = "1.0.85" diff --git a/consulrs_derive/src/error.rs b/consulrs_derive/src/error.rs index 1814329..73475b1 100644 --- a/consulrs_derive/src/error.rs +++ b/consulrs_derive/src/error.rs @@ -14,7 +14,7 @@ impl Error { /// This uses [quote_spanned!] in order to provide more accurate information /// to the compiler about the exact location of the error. pub fn new(span: Span, message: &str) -> Error { - Error(quote_spanned! { span => + Error(quote_spanned! {span=> compile_error!(#message); }) } diff --git a/src/api.rs b/src/api.rs index d591eff..050ca27 100644 --- a/src/api.rs +++ b/src/api.rs @@ -12,6 +12,7 @@ pub use crate::api::features::Features; pub mod catalog; pub mod check; +pub mod configuration; pub mod connect; pub mod features; pub mod health; @@ -205,7 +206,7 @@ where } /// Parses commonly found header fields out of response headers. -fn parse_headers(headers: &http::HeaderMap) -> ApiResponseBuilder +fn parse_headers(headers: &reqwest::header::HeaderMap) -> ApiResponseBuilder where T: DeserializeOwned + Send + Sync, { diff --git a/src/api/check/common.rs b/src/api/check/common.rs index 4170357..c7891d6 100644 --- a/src/api/check/common.rs +++ b/src/api/check/common.rs @@ -62,7 +62,7 @@ pub struct AgentServiceCheck { #[serde(rename = "TLSServerName")] pub tls_server_name: Option, #[serde(rename = "TLSSkipVerify")] - pub tlk_skip_verify: Option, + pub tls_skip_verify: Option, #[serde(rename = "TTL")] pub ttl: Option, } diff --git a/src/api/check/requests.rs b/src/api/check/requests.rs index 1f1231c..96914f7 100644 --- a/src/api/check/requests.rs +++ b/src/api/check/requests.rs @@ -77,7 +77,7 @@ pub struct RegisterCheckRequest { #[serde(rename = "TLSServerName")] pub tls_server_name: Option, #[serde(rename = "TLSSkipVerify")] - pub tls_skip_verify: Option, + pub tls_skip_verify: Option, #[serde(rename = "TTL")] pub ttl: Option, } diff --git a/src/api/configuration.rs b/src/api/configuration.rs new file mode 100644 index 0000000..92bc786 --- /dev/null +++ b/src/api/configuration.rs @@ -0,0 +1,2 @@ +pub mod common; +pub mod requests; diff --git a/src/api/configuration/common.rs b/src/api/configuration/common.rs new file mode 100644 index 0000000..ed47eda --- /dev/null +++ b/src/api/configuration/common.rs @@ -0,0 +1,26 @@ +use derive_builder::Builder; +use serde::{Deserialize, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::Debug; + +#[skip_serializing_none] +#[derive(Builder, Clone, Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "PascalCase")] +#[builder(setter(into, strip_option), default)] +pub struct AgentConfiguration { + pub config: Option, +} + +#[skip_serializing_none] +#[derive(Builder, Clone, Debug, Default, Deserialize, Serialize)] +#[serde(rename_all = "PascalCase")] +#[builder(setter(into, strip_option), default)] +pub struct AgentConfig { + pub datacenter: Option, + pub node_name: Option, + #[serde(rename = "NodeID")] + pub node_id: Option, + pub server: Option, + pub revision: Option, + pub version: Option, +} diff --git a/src/api/configuration/requests.rs b/src/api/configuration/requests.rs new file mode 100644 index 0000000..0476e3e --- /dev/null +++ b/src/api/configuration/requests.rs @@ -0,0 +1,25 @@ +use crate::api::Features; + +use super::common::AgentConfiguration; +use consulrs_derive::QueryEndpoint; +use derive_builder::Builder; +use rustify_derive::Endpoint; +use serde::Serialize; +use std::fmt::Debug; + +/// ## Read configuration +/// This endpoint returns the configuration and member information of the local agent. +/// +/// * Path: agent/self +/// * Method: GET +/// * Response: [AgentConfiguration] +/// * Reference: https://developer.hashicorp.com/consul/api-docs/agent#read-configuration +#[derive(Builder, Debug, Default, Endpoint, QueryEndpoint)] +#[endpoint(path = "agent/self", response = "AgentConfiguration", builder = "true")] +#[builder(setter(into, strip_option), default)] +pub struct ReadConfigurationRequest { + #[endpoint(skip)] + pub features: Option, + #[endpoint(query)] + pub ns: Option, +} diff --git a/src/api/kv/common.rs b/src/api/kv/common.rs index 2e6252c..f627206 100644 --- a/src/api/kv/common.rs +++ b/src/api/kv/common.rs @@ -14,7 +14,8 @@ impl TryInto> for Base64String { type Error = ClientError; fn try_into(self) -> Result, Self::Error> { - base64::decode(&self.0).map_err(|e| ClientError::Base64DecodeError { source: e }) + base64::Engine::decode(&base64::engine::general_purpose::STANDARD, self.0) + .map_err(|e| ClientError::Base64DecodeError { source: e }) } } diff --git a/src/configuration.rs b/src/configuration.rs new file mode 100644 index 0000000..70a004b --- /dev/null +++ b/src/configuration.rs @@ -0,0 +1,25 @@ +use crate::{ + api::{ + self, + configuration::{ + common::AgentConfiguration, + requests::{ReadConfigurationRequest, ReadConfigurationRequestBuilder}, + }, + ApiResponse, + }, + client::Client, + error::ClientError, +}; + +/// Reads the configuration and member information of the local agent. +/// +/// See [ReadConfigurationRequest] +#[instrument(skip(client, opts), err)] +pub async fn read( + client: &impl Client, + opts: Option<&mut ReadConfigurationRequestBuilder>, +) -> Result, ClientError> { + let mut t = ReadConfigurationRequest::builder(); + let endpoint = opts.unwrap_or(&mut t).build().unwrap(); + api::exec_with_result(client, endpoint).await +} diff --git a/src/lib.rs b/src/lib.rs index 6501e45..7ff7d53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -173,6 +173,7 @@ pub mod api; pub mod catalog; pub mod check; pub mod client; +pub mod configuration; pub mod error; pub mod health; pub mod kv;