Refactor haproxy rt api
This commit is contained in:
parent
c9431c62b8
commit
27caa5edac
108
src/haproxy.rs
108
src/haproxy.rs
@ -1,6 +1,9 @@
|
|||||||
use std::{path::Path, time::Duration};
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use tokio::{io::{AsyncReadExt, AsyncWriteExt}, time::timeout};
|
use std::{path::Path, time::Duration};
|
||||||
|
use tokio::{
|
||||||
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
|
time::timeout,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum HaProxyErr {
|
pub enum HaProxyErr {
|
||||||
@ -28,49 +31,86 @@ impl HaProxyApi {
|
|||||||
let cert_path = cert_path.as_ref();
|
let cert_path = cert_path.as_ref();
|
||||||
let cert_name = cert_path.file_name().unwrap().to_string_lossy().to_string();
|
let cert_name = cert_path.file_name().unwrap().to_string_lossy().to_string();
|
||||||
let cert_content = tokio::fs::read_to_string(cert_path).await.unwrap();
|
let cert_content = tokio::fs::read_to_string(cert_path).await.unwrap();
|
||||||
let haproxy_ssl_dir = &self.cert_dir;
|
let haproxy_cert_path = format!("{}/{cert_name}", &self.cert_dir);
|
||||||
|
|
||||||
debug!("Trying to update haproxy cert in memory: {haproxy_ssl_dir}/{cert_name} <- {}", cert_path.display());
|
debug!(
|
||||||
|
"Trying to update haproxy cert in memory: {}/{cert_name} <- {}",
|
||||||
|
&self.cert_dir,
|
||||||
|
cert_path.display()
|
||||||
|
);
|
||||||
|
|
||||||
// Check for active transactions and abort them
|
// Check for active transactions and abort them
|
||||||
let resp = self.send(&format!("show ssl cert")).await?;
|
let resp = self.send(&format!("show ssl cert")).await?;
|
||||||
let transactions = resp.lines().filter(|line| line.starts_with("*")).map(|line| &line[1..]).collect::<Vec<_>>();
|
let transactions = resp
|
||||||
|
.lines()
|
||||||
|
.filter(|line| line.starts_with("*"))
|
||||||
|
.map(|line| &line[1..])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
for transaction in transactions {
|
for transaction in transactions {
|
||||||
self.send(&format!("abort ssl cert {transaction}")).await?;
|
self.abort_cert(transaction).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to create a new certificate in memory. This will do nothing when existing
|
self.new_cert(&haproxy_cert_path).await?;
|
||||||
let resp = self.send(&format!("new ssl cert {haproxy_ssl_dir}/{cert_name}")).await?;
|
self.set_cert(&haproxy_cert_path, &cert_content).await?;
|
||||||
|
self.commit_ssl_cert(&haproxy_cert_path).await?;
|
||||||
if !resp.contains("already exists") && !resp.contains("New empty certificate store ") {
|
self.add_ssl_crt_list(&self.cert_dir, &haproxy_cert_path)
|
||||||
return Err(HaProxyErr::UpdateFailed);
|
.await?;
|
||||||
}
|
|
||||||
|
|
||||||
// Set the cert data in memory to the new cert. This beginns a transaction
|
|
||||||
let resp = self.send(&format!("set ssl cert {haproxy_ssl_dir}/{cert_name} <<\n{cert_content}")).await?;
|
|
||||||
|
|
||||||
if !resp.contains("Transaction created") {
|
|
||||||
return Err(HaProxyErr::UpdateFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit the cert data transaction
|
|
||||||
let resp = self.send(&format!("commit ssl cert {haproxy_ssl_dir}/{cert_name}")).await?;
|
|
||||||
|
|
||||||
if !resp.contains("Success") {
|
|
||||||
self.send(&format!("abort ssl cert {haproxy_ssl_dir}/{cert_name}")).await?;
|
|
||||||
return Err(HaProxyErr::UpdateFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to add the certificate to the active list. This will do nothing if it is contained already
|
|
||||||
let resp = self.send(&format!("add ssl crt-list {haproxy_ssl_dir} <<\n{haproxy_ssl_dir}/{cert_name}\n")).await?;
|
|
||||||
|
|
||||||
if !resp.contains("already exists") && !resp.contains("Inserting certificate") {
|
|
||||||
return Err(HaProxyErr::UpdateFailed);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// See: https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/abort-ssl-cert/
|
||||||
|
pub async fn abort_cert(&self, cert_path: &str) -> Result<(), HaProxyErr> {
|
||||||
|
self.send(&format!("abort ssl cert {cert_path}")).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See: https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/new-ssl-cert/
|
||||||
|
pub async fn new_cert(&self, cert_path: &str) -> Result<(), HaProxyErr> {
|
||||||
|
let resp = self.send(&format!("new ssl cert {cert_path}")).await?;
|
||||||
|
if !resp.contains("already exists") && !resp.contains("New empty certificate store ") {
|
||||||
|
return Err(HaProxyErr::UpdateFailed);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See: https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/set-ssl-cert/
|
||||||
|
pub async fn set_cert(&self, cert_path: &str, cert_content: &str) -> Result<(), HaProxyErr> {
|
||||||
|
let resp = self
|
||||||
|
.send(&format!("set ssl cert {cert_path} <<\n{cert_content}"))
|
||||||
|
.await?;
|
||||||
|
if !resp.contains("Transaction created") {
|
||||||
|
return Err(HaProxyErr::UpdateFailed);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See: https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/commit-ssl-cert/
|
||||||
|
pub async fn commit_ssl_cert(&self, cert_path: &str) -> Result<(), HaProxyErr> {
|
||||||
|
let resp = self.send(&format!("commit ssl cert {cert_path}")).await?;
|
||||||
|
if !resp.contains("Success") {
|
||||||
|
self.send(&format!("abort ssl cert {cert_path}")).await?;
|
||||||
|
return Err(HaProxyErr::UpdateFailed);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See: https://www.haproxy.com/documentation/hapee/latest/api/runtime-api/add-ssl-crt-list/
|
||||||
|
pub async fn add_ssl_crt_list(
|
||||||
|
&self,
|
||||||
|
list_path: &str,
|
||||||
|
cert_path: &str,
|
||||||
|
) -> Result<(), HaProxyErr> {
|
||||||
|
let resp = self
|
||||||
|
.send(&format!("add ssl crt-list {list_path} <<\n{cert_path}\n"))
|
||||||
|
.await?;
|
||||||
|
if !resp.contains("already exists") && !resp.contains("Inserting certificate") {
|
||||||
|
return Err(HaProxyErr::UpdateFailed);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a string command to the haproxy runtime api and return the response string
|
||||||
pub async fn send(&self, cmd: &str) -> Result<String, HaProxyErr> {
|
pub async fn send(&self, cmd: &str) -> Result<String, HaProxyErr> {
|
||||||
debug!("[Haproxy] send> '{cmd}'");
|
debug!("[Haproxy] send> '{cmd}'");
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user