forked from kemitix/git-next
feat(server): allow specifying id address and port to bind to
Closes kemitix/git-next#44
This commit is contained in:
parent
daa40e7621
commit
1cd56d953e
6 changed files with 57 additions and 8 deletions
|
@ -1,5 +1,9 @@
|
||||||
|
[http]
|
||||||
|
addr = "0.0.0.0"
|
||||||
|
port = 8080
|
||||||
|
|
||||||
[webhook]
|
[webhook]
|
||||||
url = "https://localhost:8080/webhook"
|
url = "https://localhost:8080"
|
||||||
|
|
||||||
[storage]
|
[storage]
|
||||||
path = "./data"
|
path = "./data"
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
use kxio::{fs::FileSystem, network::Network};
|
use kxio::{fs::FileSystem, network::Network};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
use crate::server::{
|
use crate::server::{
|
||||||
actors::{
|
actors::{
|
||||||
|
@ -62,6 +62,10 @@ impl Handler<ServerConfig> for Server {
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)] // TODO: (#75) reduce complexity
|
#[allow(clippy::cognitive_complexity)] // TODO: (#75) reduce complexity
|
||||||
fn handle(&mut self, msg: ServerConfig, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: ServerConfig, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let Ok(socket_addr) = msg.http() else {
|
||||||
|
warn!("Unable to parse http.addr");
|
||||||
|
return;
|
||||||
|
};
|
||||||
if let Some(webhook) = self.webhook.take() {
|
if let Some(webhook) = self.webhook.take() {
|
||||||
webhook.do_send(ShutdownWebhook);
|
webhook.do_send(ShutdownWebhook);
|
||||||
}
|
}
|
||||||
|
@ -103,7 +107,7 @@ impl Handler<ServerConfig> for Server {
|
||||||
.for_each(|msg| webhook_router.do_send(msg));
|
.for_each(|msg| webhook_router.do_send(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
let webhook = WebhookActor::new(webhook_router.recipient()).start();
|
let webhook = WebhookActor::new(socket_addr, webhook_router.recipient()).start();
|
||||||
self.webhook.replace(webhook);
|
self.webhook.replace(webhook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ mod message;
|
||||||
mod router;
|
mod router;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
pub use message::WebhookMessage;
|
pub use message::WebhookMessage;
|
||||||
|
@ -13,14 +15,16 @@ use tracing::Instrument;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WebhookActor {
|
pub struct WebhookActor {
|
||||||
|
socket_addr: SocketAddr,
|
||||||
span: tracing::Span,
|
span: tracing::Span,
|
||||||
spawn_handle: Option<actix::SpawnHandle>,
|
spawn_handle: Option<actix::SpawnHandle>,
|
||||||
message_receiver: Recipient<WebhookMessage>,
|
message_receiver: Recipient<WebhookMessage>,
|
||||||
}
|
}
|
||||||
impl WebhookActor {
|
impl WebhookActor {
|
||||||
pub fn new(message_receiver: Recipient<WebhookMessage>) -> Self {
|
pub fn new(socket_addr: SocketAddr, message_receiver: Recipient<WebhookMessage>) -> Self {
|
||||||
let span = tracing::info_span!("WebhookActor");
|
let span = tracing::info_span!("WebhookActor");
|
||||||
Self {
|
Self {
|
||||||
|
socket_addr,
|
||||||
span,
|
span,
|
||||||
message_receiver,
|
message_receiver,
|
||||||
spawn_handle: None,
|
spawn_handle: None,
|
||||||
|
@ -32,7 +36,7 @@ impl Actor for WebhookActor {
|
||||||
fn started(&mut self, ctx: &mut Self::Context) {
|
fn started(&mut self, ctx: &mut Self::Context) {
|
||||||
let _gaurd = self.span.enter();
|
let _gaurd = self.span.enter();
|
||||||
let address: Recipient<WebhookMessage> = self.message_receiver.clone();
|
let address: Recipient<WebhookMessage> = self.message_receiver.clone();
|
||||||
let server = server::start(address);
|
let server = server::start(self.socket_addr, address);
|
||||||
let spawn_handle = ctx.spawn(server.in_current_span().into_actor(self));
|
let spawn_handle = ctx.spawn(server.in_current_span().into_actor(self));
|
||||||
self.spawn_handle.replace(spawn_handle);
|
self.spawn_handle.replace(spawn_handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use crate::server::actors::webhook::message::WebhookMessage;
|
use crate::server::actors::webhook::message::WebhookMessage;
|
||||||
|
|
||||||
pub async fn start(address: actix::prelude::Recipient<super::message::WebhookMessage>) {
|
pub async fn start(
|
||||||
|
socket_addr: SocketAddr,
|
||||||
|
address: actix::prelude::Recipient<super::message::WebhookMessage>,
|
||||||
|
) {
|
||||||
// start webhook server
|
// start webhook server
|
||||||
use warp::Filter;
|
use warp::Filter;
|
||||||
// Define the Warp route to handle incoming HTTP requests
|
// Define the Warp route to handle incoming HTTP requests
|
||||||
|
@ -49,6 +54,6 @@ pub async fn start(address: actix::prelude::Recipient<super::message::WebhookMes
|
||||||
);
|
);
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
info!("Starting webhook server: http://0.0.0.0:8080/");
|
info!("Starting webhook server: {}", socket_addr);
|
||||||
warp::serve(route).run(([0, 0, 0, 0], 8080)).await;
|
warp::serve(route).run(socket_addr).await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@ pub mod load;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
|
net::SocketAddr,
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -21,6 +23,7 @@ pub enum Error {
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
KxIoFs(kxio::fs::Error),
|
KxIoFs(kxio::fs::Error),
|
||||||
TomlDe(toml::de::Error),
|
TomlDe(toml::de::Error),
|
||||||
|
AddressParse(std::net::AddrParseError),
|
||||||
}
|
}
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
|
|
||||||
|
@ -30,6 +33,7 @@ type Result<T> = core::result::Result<T, Error>;
|
||||||
#[derive(Debug, PartialEq, Eq, Deserialize, Message)]
|
#[derive(Debug, PartialEq, Eq, Deserialize, Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
|
http: Http,
|
||||||
webhook: Webhook,
|
webhook: Webhook,
|
||||||
storage: ServerStorage,
|
storage: ServerStorage,
|
||||||
forge: HashMap<String, ForgeConfig>,
|
forge: HashMap<String, ForgeConfig>,
|
||||||
|
@ -56,9 +60,29 @@ impl ServerConfig {
|
||||||
pub const fn webhook(&self) -> &Webhook {
|
pub const fn webhook(&self) -> &Webhook {
|
||||||
&self.webhook
|
&self.webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn http(&self) -> Result<SocketAddr> {
|
||||||
|
self.http.socket_addr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines the port the server will listen to for incoming webhooks messages
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||||
|
pub struct Http {
|
||||||
|
addr: String,
|
||||||
|
port: u16,
|
||||||
|
}
|
||||||
|
impl Http {
|
||||||
|
fn socket_addr(&self) -> Result<SocketAddr> {
|
||||||
|
Ok(SocketAddr::from_str(&format!(
|
||||||
|
"{}:{}",
|
||||||
|
self.addr, self.port
|
||||||
|
))?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the Webhook Forges should send updates to
|
/// Defines the Webhook Forges should send updates to
|
||||||
|
/// Must be an address that is accessible from the remote forge
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
|
||||||
pub struct Webhook {
|
pub struct Webhook {
|
||||||
url: String,
|
url: String,
|
||||||
|
|
|
@ -16,6 +16,10 @@ fn load_should_parse_server_config() -> Result<()> {
|
||||||
fs.file_write(
|
fs.file_write(
|
||||||
&fs.base().join("git-next-server.toml"),
|
&fs.base().join("git-next-server.toml"),
|
||||||
r#"
|
r#"
|
||||||
|
[http]
|
||||||
|
addr = "0.0.0.0"
|
||||||
|
port = 8080
|
||||||
|
|
||||||
[webhook]
|
[webhook]
|
||||||
url = "http://localhost:9909/webhook"
|
url = "http://localhost:9909/webhook"
|
||||||
|
|
||||||
|
@ -43,6 +47,10 @@ fn load_should_parse_server_config() -> Result<()> {
|
||||||
?;
|
?;
|
||||||
let_assert!(Ok(config) = ServerConfig::load(&fs));
|
let_assert!(Ok(config) = ServerConfig::load(&fs));
|
||||||
let expected = ServerConfig {
|
let expected = ServerConfig {
|
||||||
|
http: Http {
|
||||||
|
addr: "0.0.0.0".to_string(),
|
||||||
|
port: 8080,
|
||||||
|
},
|
||||||
webhook: Webhook {
|
webhook: Webhook {
|
||||||
url: "http://localhost:9909/webhook".to_string(),
|
url: "http://localhost:9909/webhook".to_string(),
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue