Skip to content

Commit

Permalink
feat: implemented resource key and update data to spec
Browse files Browse the repository at this point in the history
  • Loading branch information
paulobressan committed Aug 2, 2024
1 parent 1600e6d commit edcbea6
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 27 deletions.

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

11 changes: 6 additions & 5 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions src/domain/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub struct ResourceCreated {
pub project_id: String,
pub project_namespace: String,
pub kind: String,
pub data: String,
pub spec: String,
pub status: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
Expand Down Expand Up @@ -138,7 +138,7 @@ mod tests {
project_id: Uuid::new_v4().to_string(),
project_namespace: "prj-test".into(),
kind: "CardanoNode".into(),
data: "{\"spec\":{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}}".into(),
spec: "{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}".into(),
status: ResourceStatus::Active.to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
Expand Down
5 changes: 4 additions & 1 deletion src/domain/resource/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use kube::{
api::{ApiResource, DynamicObject, ObjectMeta},
ResourceExt,
};
use serde_json::json;
use tracing::info;

use crate::domain::event::{ResourceCreated, ResourceDeleted};
Expand All @@ -27,7 +28,9 @@ pub async fn apply_manifest(
namespace: Some(evt.project_namespace),
..Default::default()
};
obj.data = serde_json::from_str(&evt.data)?;

let spec = serde_json::from_str(&evt.spec)?;
obj.data = json!({ "spec": serde_json::Value::Object(spec) });

cluster.create(&obj).await?;

Expand Down
39 changes: 33 additions & 6 deletions src/domain/resource/command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::sync::Arc;

use anyhow::{bail, ensure, Result};
use anyhow::{bail, ensure, Error, Result};
use argon2::{password_hash::SaltString, Argon2};
use bech32::{Bech32m, Hrp};
use chrono::Utc;
use rand::rngs::OsRng;
use tracing::info;
use uuid::Uuid;

Expand Down Expand Up @@ -38,12 +41,17 @@ pub async fn create(
bail!("project doesnt exist")
};

let auth_token = build_auth_token(&project.id, &cmd.id, &cmd.kind)?;

let mut spec = cmd.spec.clone();
spec.insert("authToken".into(), serde_json::Value::String(auth_token));

let evt = ResourceCreated {
id: cmd.id,
project_id: project.id,
project_namespace: project.namespace,
kind: cmd.kind.clone(),
data: cmd.data,
spec: serde_json::to_string(&spec)?,
status: ResourceStatus::Active.to_string(),
created_at: Utc::now(),
updated_at: Utc::now(),
Expand Down Expand Up @@ -116,6 +124,24 @@ fn assert_project_resource(project: &Project, resource: &Resource) -> Result<()>
Ok(())
}

pub fn build_auth_token(project_id: &str, resource_id: &str, kind: &str) -> Result<String> {
let argon2 = Argon2::default();
let key = format!("{project_id}{resource_id}").as_bytes().to_vec();

let salt = SaltString::generate(&mut OsRng);

let mut output = vec![0; 8];
argon2
.hash_password_into(&key, salt.as_str().as_bytes(), &mut output)
.map_err(|err| Error::msg(err.to_string()))?;

let prefix = format!("dmtr_{}", kind.to_lowercase());
let hrp = Hrp::parse(&prefix)?;
let bech = bech32::encode::<Bech32m>(hrp, &output)?;

Ok(bech)
}

#[derive(Debug, Clone)]
pub struct FetchCmd {
pub credential: Credential,
Expand Down Expand Up @@ -147,24 +173,25 @@ impl FetchCmd {
}
}

pub type Spec = serde_json::value::Map<String, serde_json::Value>;
#[derive(Debug, Clone)]
pub struct CreateCmd {
pub credential: Credential,
pub id: String,
pub project_id: String,
pub kind: String,
pub data: String,
pub spec: Spec,
}
impl CreateCmd {
pub fn new(credential: Credential, project_id: String, kind: String, data: String) -> Self {
pub fn new(credential: Credential, project_id: String, kind: String, spec: Spec) -> Self {
let id = Uuid::new_v4().to_string();

Self {
credential,
id,
project_id,
kind,
data,
spec,
}
}
}
Expand Down Expand Up @@ -240,7 +267,7 @@ mod tests {
id: Uuid::new_v4().to_string(),
project_id: Uuid::new_v4().to_string(),
kind: "CardanoNode".into(),
data: "{\"spec\":{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}}".into(),
spec: serde_json::Map::new(),
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/domain/resource/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct Resource {
pub id: String,
pub project_id: String,
pub kind: String,
pub data: String,
pub spec: String,
pub status: ResourceStatus,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
Expand All @@ -26,7 +26,7 @@ impl TryFrom<ResourceCreated> for Resource {
id: value.id,
project_id: value.project_id,
kind: value.kind,
data: value.data,
spec: value.spec,
status: value.status.parse()?,
created_at: value.created_at,
updated_at: value.updated_at,
Expand Down Expand Up @@ -71,7 +71,7 @@ mod tests {
id: Uuid::new_v4().to_string(),
project_id: Uuid::new_v4().to_string(),
kind: "CardanoNode".into(),
data: "{\"spec\":{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}}".into(),
spec: "{\"operatorVersion\":\"1\",\"kupoVersion\":\"v1\",\"network\":\"mainnet\",\"pruneUtxo\":false,\"throughputTier\":\"0\"}".into(),
status: ResourceStatus::Active,
created_at: Utc::now(),
updated_at: Utc::now(),
Expand Down
2 changes: 1 addition & 1 deletion src/driven/cache/migrations/20240606_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS resource (
id TEXT PRIMARY KEY NOT NULL,
project_id TEXT NOT NULL,
kind TEXT NOT NULL,
data TEXT NOT NULL,
spec TEXT NOT NULL,
status TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
Expand Down
10 changes: 5 additions & 5 deletions src/driven/cache/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl ResourceDrivenCache for SqliteResourceDrivenCache {
r.id,
r.project_id,
r.kind,
r.data,
r.spec,
r.status,
r.created_at,
r.updated_at
Expand All @@ -53,7 +53,7 @@ impl ResourceDrivenCache for SqliteResourceDrivenCache {
r.id,
r.project_id,
r.kind,
r.data,
r.spec,
r.status,
r.created_at,
r.updated_at
Expand All @@ -77,7 +77,7 @@ impl ResourceDrivenCache for SqliteResourceDrivenCache {
id,
project_id,
kind,
data,
spec,
status,
created_at,
updated_at
Expand All @@ -87,7 +87,7 @@ impl ResourceDrivenCache for SqliteResourceDrivenCache {
resource.id,
resource.project_id,
resource.kind,
resource.data,
resource.spec,
status,
resource.created_at,
resource.updated_at
Expand Down Expand Up @@ -127,7 +127,7 @@ impl FromRow<'_, SqliteRow> for Resource {
id: row.try_get("id")?,
project_id: row.try_get("project_id")?,
kind: row.try_get("kind")?,
data: row.try_get("data")?,
spec: row.try_get("spec")?,
status: status
.parse()
.map_err(|err: Error| sqlx::Error::Decode(err.into()))?,
Expand Down
12 changes: 10 additions & 2 deletions src/drivers/grpc/resource.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use dmtri::demeter::ops::v1alpha::{self as proto, DeleteResourceResponse};
use serde_json::Value;
use std::sync::Arc;
use tonic::{async_trait, Status};

Expand Down Expand Up @@ -65,7 +66,14 @@ impl proto::resource_service_server::ResourceService for ResourceServiceImpl {

let req = request.into_inner();

let cmd = command::CreateCmd::new(credential, req.project_id, req.kind, req.data);
let value = serde_json::from_str(&req.spec)
.map_err(|_| Status::failed_precondition("spec must be a json"))?;
let spec = match value {
Value::Object(v) => Ok(v),
_ => Err(Status::failed_precondition("invalid spec json")),
}?;

let cmd = command::CreateCmd::new(credential, req.project_id, req.kind, spec);

command::create(self.project_cache.clone(), self.event.clone(), cmd.clone())
.await
Expand Down Expand Up @@ -113,7 +121,7 @@ impl From<Resource> for proto::Resource {
Self {
id: value.id,
kind: value.kind,
data: value.data,
spec: value.spec,
status: value.status.to_string(),
created_at: value.created_at.to_rfc3339(),
updated_at: value.updated_at.to_rfc3339(),
Expand Down

0 comments on commit edcbea6

Please sign in to comment.