Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting environment variables #6

Merged
merged 16 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions db/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CREATE TABLE envs (
id UUID NOT NULL,
name TEXT NOT NULL,
value TEXT NOT NULL,
-- project id can be nullable
project_id UUID NOT NULL,
owner_id UUID NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
Expand Down
12 changes: 10 additions & 2 deletions dosei/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@ pub async fn start_server(config: &'static Config) -> anyhow::Result<()> {
cluster::start_node(config);
cron::start_job_manager(config, Arc::clone(&shared_pool));
let app = Router::new()
.route("/envs", routing::post(secret::api_set_envs))
.route("/envs", routing::get(secret::api_get_envs))
.route("/envs/:owner_id", routing::post(secret::api_set_envs))
.route(
"/envs/:owner_id/:project_id",
routing::post(secret::api_set_envs),
)
.route("/envs/:owner_id", routing::get(secret::api_get_envs))
.route(
"/envs/:owner_id/:project_id",
routing::get(secret::api_get_envs),
)
.route("/cron-jobs", routing::post(cron::api_create_job))
.route("/cron-jobs", routing::get(cron::api_get_cron_jobs))
.layer(Extension(Arc::clone(&shared_pool)));
Expand Down
81 changes: 64 additions & 17 deletions dosei/src/server/secret.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,80 @@
use crate::schema::Secret;
use axum::extract::Query;
use axum::extract::Path;
use axum::http::StatusCode;
use axum::{Extension, Json};
use chrono::Utc;
use log::error;
use serde::Deserialize;
use sqlx::{Pool, Postgres};
use std::collections::HashMap;
use std::sync::Arc;
use uuid::Uuid;

pub async fn api_get_envs(pool: Extension<Arc<Pool<Postgres>>>) -> Json<Vec<Secret>> {
let recs = sqlx::query_as!(Secret, "SELECT * from envs")
.fetch_all(&**pool)
.await
.unwrap();
Json(recs)
// TODO: Return owner envs when project_id provided as well.
// if conflicting owner env name and project override with project level one.
pub async fn api_get_envs(
pool: Extension<Arc<Pool<Postgres>>>,
Path(params): Path<EnvsPathParams>,
) -> Result<Json<Vec<Secret>>, StatusCode> {
match sqlx::query_as!(
Secret,
"SELECT * FROM envs WHERE project_id = $1::uuid and owner_id = $2::uuid",
params.get_project_id(),
params.owner_id
)
.fetch_all(&**pool)
.await
{
Ok(recs) => Ok(Json(recs)),
Err(err) => {
error!("Error in retrieving secret: {:?}", err);
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
}
}

pub async fn api_set_envs(
pool: Extension<Arc<Pool<Postgres>>>,
Query(query): Query<SetEnvsQueryParams>,
Path(params): Path<EnvsPathParams>,
Json(body): Json<HashMap<String, String>>,
) -> Json<HashMap<String, String>> {
println!("{:?}", body);
println!("{query:?}");
let rec = HashMap::new();
Json(rec)
) -> Result<Json<Vec<Secret>>, StatusCode> {
let mut updated_secrets: Vec<Secret> = Vec::new();

for (name, value) in body {
let query = sqlx::query_as!(
Secret,
"INSERT INTO envs (id, name, value, owner_id, project_id, updated_at, created_at) VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (owner_id, project_id, name) DO UPDATE
SET value = EXCLUDED.value, updated_at = EXCLUDED.updated_at
RETURNING *",
Uuid::new_v4(),
name,
value,
params.owner_id,
params.get_project_id(),
Utc::now(),
Utc::now()
);

match query.fetch_one(&**pool).await {
Ok(secret) => updated_secrets.push(secret),
Err(err) => {
error!("Error in upserting and retrieving secret: {:?}", err);
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
}
}
Ok(Json(updated_secrets))
}

#[allow(dead_code)]
#[derive(Deserialize, Debug)]
pub struct SetEnvsQueryParams {
owner_name: Option<String>,
project_name: Option<String>,
pub struct EnvsPathParams {
owner_id: Uuid,
project_id: Option<Uuid>,
}

impl EnvsPathParams {
pub fn get_project_id(&self) -> Uuid {
self.project_id.unwrap_or_else(Uuid::default)
}
}
Loading