got basic system for passing configs back and forth with URL working
This commit is contained in:
parent
9e724d3903
commit
130581d61e
1
.env.dev
1
.env.dev
@ -1,3 +1,4 @@
|
||||
export GATEWAY_PASSPHRASE=foobar
|
||||
export GATEWAY_ORIGIN_STORE_GIT_DIR_PATH=/tmp/gateway_dev_env/origin/git
|
||||
export GATEWAY_DOMAIN_CHECKER_TARGET_CNAME=gateway.example.com
|
||||
export GATEWAY_DOMAIN_CONFIG_STORE_DIR_PATH=/tmp/gateway_dev_env/domain/config
|
||||
|
12
src/main.rs
12
src/main.rs
@ -15,6 +15,9 @@ struct Cli {
|
||||
#[arg(long, default_value_t = SocketAddr::from_str("127.0.0.1:3030").unwrap(), env = "GATEWAY_HTTP_LISTEN_ADDR")]
|
||||
http_listen_addr: SocketAddr,
|
||||
|
||||
#[arg(long, required = true, env = "GATEWAY_PASSPHRASE")]
|
||||
passphrase: String,
|
||||
|
||||
#[arg(long, required = true, env = "GATEWAY_ORIGIN_STORE_GIT_DIR_PATH")]
|
||||
origin_store_git_dir_path: path::PathBuf,
|
||||
|
||||
@ -59,7 +62,7 @@ async fn main() {
|
||||
.expect("git origin store initialized");
|
||||
|
||||
let domain_checker = gateway::domain::checker::new(
|
||||
config.domain_checker_target_cname,
|
||||
config.domain_checker_target_cname.clone(),
|
||||
&config.domain_checker_resolver_addr,
|
||||
)
|
||||
.expect("domain checker initialized");
|
||||
@ -69,7 +72,12 @@ async fn main() {
|
||||
|
||||
let manager = gateway::domain::manager::new(origin_store, domain_config_store, domain_checker);
|
||||
|
||||
let service = gateway::service::new(manager).expect("service initialized");
|
||||
let service = gateway::service::new(
|
||||
manager,
|
||||
config.domain_checker_target_cname,
|
||||
config.passphrase,
|
||||
)
|
||||
.expect("service initialized");
|
||||
|
||||
let (addr, server) =
|
||||
warp::serve(service).bind_with_graceful_shutdown(config.http_listen_addr, async {
|
||||
|
@ -7,6 +7,7 @@ use warp::Filter;
|
||||
use crate::domain;
|
||||
|
||||
pub mod http_tpl;
|
||||
mod util;
|
||||
|
||||
/*
|
||||
* POST /domain/config (domain, config, secret, init?) -> token?
|
||||
@ -21,6 +22,9 @@ where
|
||||
DM: domain::manager::Manager,
|
||||
{
|
||||
domain_manager: sync::Arc<DM>,
|
||||
target_cname: sync::Arc<domain::Name>,
|
||||
passphrase: sync::Arc<String>,
|
||||
|
||||
handlebars: Handlebars<'a>,
|
||||
query_args: HashMap<String, String>,
|
||||
}
|
||||
@ -71,6 +75,8 @@ where
|
||||
|
||||
pub fn new<DM>(
|
||||
manager: DM,
|
||||
target_cname: domain::Name,
|
||||
passphrase: String,
|
||||
) -> Result<
|
||||
impl warp::Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone + 'static,
|
||||
Box<dyn Error>,
|
||||
@ -79,12 +85,16 @@ where
|
||||
DM: domain::manager::Manager + 'static,
|
||||
{
|
||||
let manager = sync::Arc::new(manager);
|
||||
let target_cname = sync::Arc::new(target_cname);
|
||||
let passphrase = sync::Arc::new(passphrase);
|
||||
|
||||
let hbs = sync::Arc::new(self::http_tpl::get()?);
|
||||
let with_render_ctx = warp::any()
|
||||
.and(warp::query::<HashMap<String, String>>())
|
||||
.map(move |query_args: HashMap<String, String>| RenderContext {
|
||||
domain_manager: manager.clone(),
|
||||
target_cname: target_cname.clone(),
|
||||
passphrase: passphrase.clone(),
|
||||
handlebars: hbs.clone(),
|
||||
query_args,
|
||||
});
|
||||
@ -111,28 +121,87 @@ where
|
||||
domain: domain::Name,
|
||||
}
|
||||
|
||||
let domain_get = warp::get()
|
||||
.and(with_render_ctx.clone())
|
||||
.and(warp::path("domain.html"))
|
||||
.and(warp::query::<DomainGetNewRequest>())
|
||||
.map(
|
||||
move |render_ctx: RenderContext<'_, DM>, req: DomainGetNewRequest| {
|
||||
#[derive(Serialize)]
|
||||
struct DomainGetNewResponse {
|
||||
domain: domain::Name,
|
||||
config: Option<domain::config::Config>,
|
||||
}
|
||||
|
||||
let domain_get = warp::get()
|
||||
.and(with_render_ctx.clone())
|
||||
.and(warp::path!("domain.html"))
|
||||
.and(warp::query::<DomainGetNewRequest>())
|
||||
.and(warp::query::<util::ConfigFromURL>())
|
||||
.map(
|
||||
|render_ctx: RenderContext<'_, DM>,
|
||||
req: DomainGetNewRequest,
|
||||
domain_config: util::ConfigFromURL| {
|
||||
match render_ctx.domain_manager.get_config(&req.domain) {
|
||||
Ok(_config) => panic!("TODO"),
|
||||
Err(domain::manager::GetConfigError::NotFound) => render_page(
|
||||
render_ctx,
|
||||
String::from("/domain_get_new.html"),
|
||||
DomainGetNewResponse { domain: req.domain },
|
||||
DomainGetNewResponse {
|
||||
domain: req.domain,
|
||||
config: domain_config.try_into().expect("TODO"),
|
||||
},
|
||||
),
|
||||
Err(_) => panic!("TODO"),
|
||||
Err(domain::manager::GetConfigError::Unexpected(e)) => {
|
||||
panic!("{}", e) // TODO
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
Ok(static_dir.or(index).or(domain_get))
|
||||
#[derive(Deserialize)]
|
||||
struct DomainPostRequest {
|
||||
_init: bool,
|
||||
domain: domain::Name,
|
||||
passphrase: String,
|
||||
}
|
||||
|
||||
let domain_post = warp::post()
|
||||
.and(with_render_ctx.clone())
|
||||
.and(warp::path!("domain.html"))
|
||||
.and(warp::query::<DomainPostRequest>())
|
||||
.and(warp::query::<util::ConfigFromURL>())
|
||||
.map(
|
||||
|render_ctx: RenderContext<'_, DM>,
|
||||
req: DomainPostRequest,
|
||||
domain_config: util::ConfigFromURL| {
|
||||
if req.passphrase != render_ctx.passphrase.as_str() {
|
||||
panic!("TODO")
|
||||
}
|
||||
|
||||
//if req.init {
|
||||
#[derive(Serialize)]
|
||||
struct Response {
|
||||
domain: domain::Name,
|
||||
config: domain::config::Config,
|
||||
target_cname: domain::Name,
|
||||
challenge_token: String,
|
||||
}
|
||||
|
||||
let config: Option<domain::config::Config> =
|
||||
domain_config.try_into().expect("TODO");
|
||||
let config = config.expect("TODO");
|
||||
|
||||
let config_hash = config.hash().expect("TODO");
|
||||
let target_cname = (*render_ctx.target_cname).clone();
|
||||
|
||||
return render_page(
|
||||
render_ctx,
|
||||
String::from("/domain_post_init.html"),
|
||||
Response {
|
||||
domain: req.domain,
|
||||
config: config,
|
||||
target_cname: target_cname,
|
||||
challenge_token: config_hash,
|
||||
},
|
||||
);
|
||||
//}
|
||||
},
|
||||
);
|
||||
|
||||
Ok(static_dir.or(index).or(domain_get).or(domain_post))
|
||||
}
|
||||
|
@ -10,19 +10,25 @@ automatically updated too!</p>
|
||||
<p><em>In the future Cosmux will support more backends than just git
|
||||
repos.</em></p>
|
||||
|
||||
|
||||
<form method="POST" action="/domain.html">
|
||||
<input name="init" type="hidden" value="true" />
|
||||
<input name="domain" type="hidden" value="{{ data.domain }}" />
|
||||
<input name="config_origin_descr_kind" type="hidden" value="git" />
|
||||
|
||||
<label>
|
||||
Passphrase (required during closed-beta):
|
||||
<input name="passphrase" placeholder="shhhh" required />
|
||||
</label>
|
||||
|
||||
<fieldset>
|
||||
<legend>Git Repository</legend>
|
||||
<p>
|
||||
<label>
|
||||
URL (HTTPS only):
|
||||
<input name="git_url"
|
||||
<input name="config_origin_descr_git_url"
|
||||
type="text"
|
||||
placeholder="https://example.com/some_repo.git"
|
||||
value="{{ data.config.origin_descr.Git.url }}"
|
||||
required />
|
||||
</label>
|
||||
</p>
|
||||
@ -30,12 +36,15 @@ automatically updated too!</p>
|
||||
<p>
|
||||
<label>
|
||||
Branch name:
|
||||
<input name="git_branch_name"
|
||||
<input name="config_origin_descr_git_branch_name"
|
||||
type="text"
|
||||
placeholder="main / master / etc..."
|
||||
value="{{ data.config.origin_descr.Git.branch_name }}"
|
||||
required />
|
||||
</label>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<input type="submit" value="Next" />
|
||||
|
||||
</form>
|
||||
|
37
src/service/util.rs
Normal file
37
src/service/util.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{domain, origin};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ConfigFromURL {
|
||||
config_origin_descr_kind: Option<String>,
|
||||
config_origin_descr_git_url: Option<String>,
|
||||
config_origin_descr_git_branch_name: Option<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<ConfigFromURL> for Option<domain::config::Config> {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(v: ConfigFromURL) -> Result<Self, Self::Error> {
|
||||
match v
|
||||
.config_origin_descr_kind
|
||||
.unwrap_or("".to_string())
|
||||
.as_str()
|
||||
{
|
||||
"" => Ok(None),
|
||||
"git" => Ok(Some(domain::config::Config {
|
||||
origin_descr: origin::Descr::Git {
|
||||
url: v
|
||||
.config_origin_descr_git_url
|
||||
.ok_or("config_origin_descr_git_url missing")?,
|
||||
branch_name: v
|
||||
.config_origin_descr_git_branch_name
|
||||
.ok_or("config_origin_descr_git_branch_name missing")?,
|
||||
},
|
||||
})),
|
||||
_ => Err("invalid config_origin_descr_kind".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user