#[allow(dead_code)]
use std::collections::HashMap;
use std::fs;
use tonic::codegen::StdError;
use tonic::Status;
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Endpoint};
use crate::stoo::pb::kv_service_client::KvServiceClient;
use crate::stoo_config::StooConfig;
pub mod pb {
tonic::include_proto!("_");
}
#[derive(Debug, Clone)]
pub struct Stoo {
client: KvServiceClient<Channel>,
config: StooConfig
}
#[allow(dead_code)]
impl Stoo {
pub async fn new(config: StooConfig) -> Self{
let mut endpoint = Endpoint::from_static(config.url)
.timeout(config.response_timeout)
.connect_timeout(config.connect_timeout);
if config.url.starts_with("https"){
endpoint = Self::set_ca_tls_config(&config, endpoint)
}
let client = KvServiceClient::connect(endpoint).await.unwrap();
Self{
client,
config
}
}
fn set_ca_tls_config(config: &StooConfig, endpoint: Endpoint) -> Endpoint {
let cert_pem = fs::read(config.ca_certificate).unwrap();
let mut tls_config = ClientTlsConfig::new()
.ca_certificate(Certificate::from_pem(cert_pem));
if config.domain != "" {
tls_config = tls_config.domain_name(config.domain)
}
return endpoint.clone().tls_config(tls_config).unwrap()
}
pub async fn from_endpoint<D>(endpoint: D) -> Self
where
D: TryInto<Endpoint>,
D::Error: Into<StdError>,{
let client = KvServiceClient::connect(endpoint).await.unwrap();
Self{
client,
config: Default::default(),
}
}
pub async fn get(&mut self, namespace: &str, profile: &str, key: &str) -> Result<String, String>{
let mut req = pb::GetRequest::default();
req.namespace = namespace.to_string();
req.profile = profile.to_string();
req.key = key.to_string();
self.client.get_service(req)
.await
.map(|res| res.into_inner().data)
.map_err(Self::from_status)
}
pub async fn set(&mut self, namespace: &str, profile: &str, key: &str, value: &str) -> Result<String, String>{
let mut req = pb::SetKeyRequest::default();
req.namespace = namespace.to_string();
req.profile = profile.to_string();
req.key = key.to_string();
req.value = value.to_string();
self.client.set_key_service(req).await
.map(|res| res.into_inner().data)
.map_err(Self::from_status)
}
pub async fn set_secret(&mut self, namespace: &str, profile: &str, key: &str, value: &str) -> Result<String, String>{
let mut req = pb::SetKeyRequest::default();
req.namespace = namespace.to_string();
req.profile = profile.to_string();
req.key = key.to_string();
req.value = value.to_string();
self.client.set_secret_key_service(req).await
.map(|res| res.into_inner().data)
.map_err(Self::from_status)
}
pub async fn delete(&mut self, namespace: &str, profile: &str, key: &str) -> Result<String, String>{
let mut req = pb::DeleteKeyRequest::default();
req.namespace = namespace.to_string();
req.profile = profile.to_string();
req.key = key.to_string();
self.client.delete_key_service(req).await
.map(|res| res.into_inner().data)
.map_err(Self::from_status)
}
pub async fn get_all_by_namespace_and_profile(&mut self, namespace: &str, profile: &str) -> Result<HashMap<String, String>, String>{
let mut req = pb::GetByNamespaceAndProfileRequest::default();
req.namespace = namespace.to_string();
req.profile = profile.to_string();
self.client.get_service_by_namespace_and_profile(req).await
.map(|res| res.into_inner().data)
.map_err(Self::from_status)
}
pub async fn get_default(mut self, key: &str) -> Result<String, String>{
return self.get(self.clone().config.get_default_namespace()?, self.clone().config.get_default_profile()?, key).await;
}
pub async fn set_default(mut self, key: &str, value: &str) -> Result<String, String>{
return self.set(self.clone().config.get_default_namespace()?, self.clone().config.get_default_profile()?, key, value).await;
}
pub async fn set_secret_default(mut self, key: &str, value: &str) -> Result<String, String>{
return self.set_secret(self.clone().config.get_default_namespace()?, self.clone().config.get_default_profile()?, key, value).await;
}
pub async fn delete_default(mut self, key: &str) -> Result<String, String>{
return self.delete(self.clone().config.get_default_namespace()?, self.clone().config.clone().get_default_profile()?, key).await;
}
pub async fn get_all_by_default_namespace_and_profile(mut self) -> Result<HashMap<String, String>, String>{
return self.get_all_by_namespace_and_profile(self.clone().config.get_default_namespace()?, self.clone().config.get_default_profile()?).await
}
fn from_status(status: Status) -> String {
format!("{} - {}", status.code(), status.message())
}
}