Refactor haproxy rt api
This commit is contained in:
parent
c9431c62b8
commit
27caa5edac
112
src/haproxy.rs
112
src/haproxy.rs
@ -1,6 +1,9 @@
|
||||
use std::{path::Path, time::Duration};
|
||||
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)]
|
||||
pub enum HaProxyErr {
|
||||
@ -28,49 +31,86 @@ impl HaProxyApi {
|
||||
let cert_path = cert_path.as_ref();
|
||||
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 haproxy_ssl_dir = &self.cert_dir;
|
||||
|
||||
debug!("Trying to update haproxy cert in memory: {haproxy_ssl_dir}/{cert_name} <- {}", cert_path.display());
|
||||
let haproxy_cert_path = format!("{}/{cert_name}", &self.cert_dir);
|
||||
|
||||
debug!(
|
||||
"Trying to update haproxy cert in memory: {}/{cert_name} <- {}",
|
||||
&self.cert_dir,
|
||||
cert_path.display()
|
||||
);
|
||||
|
||||
// Check for active transactions and abort them
|
||||
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 {
|
||||
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
|
||||
let resp = self.send(&format!("new ssl cert {haproxy_ssl_dir}/{cert_name}")).await?;
|
||||
|
||||
if !resp.contains("already exists") && !resp.contains("New empty certificate store ") {
|
||||
return Err(HaProxyErr::UpdateFailed);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
self.new_cert(&haproxy_cert_path).await?;
|
||||
self.set_cert(&haproxy_cert_path, &cert_content).await?;
|
||||
self.commit_ssl_cert(&haproxy_cert_path).await?;
|
||||
self.add_ssl_crt_list(&self.cert_dir, &haproxy_cert_path)
|
||||
.await?;
|
||||
|
||||
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> {
|
||||
debug!("[Haproxy] send> '{cmd}'");
|
||||
|
||||
@ -81,7 +121,7 @@ impl HaProxyApi {
|
||||
con.write_all(cmd.as_bytes())
|
||||
.await
|
||||
.map_err(|_| HaProxyErr::Connection)?;
|
||||
|
||||
|
||||
con.write_all(&[b'\n'])
|
||||
.await
|
||||
.map_err(|_| HaProxyErr::Connection)?;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user