-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: improved folder structure * fix: specs dependence
- Loading branch information
1 parent
755560c
commit 3330aac
Showing
21 changed files
with
1,049 additions
and
897 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use std::sync::Arc; | ||
|
||
use anyhow::Result; | ||
|
||
use crate::domain::event::{ProjectCreated, ProjectSecretCreated}; | ||
|
||
use super::{Project, ProjectSecret, ProjectUser}; | ||
|
||
#[async_trait::async_trait] | ||
pub trait ProjectDrivenCache: Send + Sync { | ||
async fn find(&self, user_id: &str, page: &u32, page_size: &u32) -> Result<Vec<Project>>; | ||
async fn find_by_namespace(&self, namespace: &str) -> Result<Option<Project>>; | ||
async fn find_by_id(&self, id: &str) -> Result<Option<Project>>; | ||
async fn create(&self, project: &Project) -> Result<()>; | ||
async fn create_secret(&self, secret: &ProjectSecret) -> Result<()>; | ||
async fn find_secret_by_project_id(&self, project_id: &str) -> Result<Vec<ProjectSecret>>; | ||
async fn find_user_permission( | ||
&self, | ||
user_id: &str, | ||
project_id: &str, | ||
) -> Result<Option<ProjectUser>>; | ||
} | ||
|
||
pub async fn create(cache: Arc<dyn ProjectDrivenCache>, evt: ProjectCreated) -> Result<()> { | ||
cache.create(&evt.try_into()?).await | ||
} | ||
|
||
pub async fn create_secret( | ||
cache: Arc<dyn ProjectDrivenCache>, | ||
evt: ProjectSecretCreated, | ||
) -> Result<()> { | ||
cache.create_secret(&evt.into()).await | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use mockall::mock; | ||
|
||
use super::*; | ||
|
||
mock! { | ||
pub FakeProjectDrivenCache { } | ||
|
||
#[async_trait::async_trait] | ||
impl ProjectDrivenCache for FakeProjectDrivenCache { | ||
async fn find(&self, user_id: &str, page: &u32, page_size: &u32) -> Result<Vec<Project>>; | ||
async fn find_by_namespace(&self, namespace: &str) -> Result<Option<Project>>; | ||
async fn find_by_id(&self, id: &str) -> Result<Option<Project>>; | ||
async fn create(&self, project: &Project) -> Result<()>; | ||
async fn create_secret(&self, secret: &ProjectSecret) -> Result<()>; | ||
async fn find_secret_by_project_id(&self, project_id: &str) -> Result<Vec<ProjectSecret>>; | ||
async fn find_user_permission(&self,user_id: &str, project_id: &str) -> Result<Option<ProjectUser>>; | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_create_project_cache() { | ||
let mut cache = MockFakeProjectDrivenCache::new(); | ||
cache.expect_create().return_once(|_| Ok(())); | ||
|
||
let evt = ProjectCreated::default(); | ||
|
||
let result = create(Arc::new(cache), evt).await; | ||
assert!(result.is_ok()); | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_create_project_secret_cache() { | ||
let mut cache = MockFakeProjectDrivenCache::new(); | ||
cache.expect_create_secret().return_once(|_| Ok(())); | ||
|
||
let evt = ProjectSecretCreated::default(); | ||
|
||
let result = create_secret(Arc::new(cache), evt).await; | ||
assert!(result.is_ok()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use std::sync::Arc; | ||
|
||
use anyhow::{bail, Result}; | ||
use k8s_openapi::api::core::v1::Namespace; | ||
use kube::{api::ObjectMeta, ResourceExt}; | ||
use tracing::info; | ||
|
||
use crate::domain::event::ProjectCreated; | ||
|
||
#[async_trait::async_trait] | ||
pub trait ProjectDrivenCluster: Send + Sync { | ||
async fn create(&self, namespace: &Namespace) -> Result<()>; | ||
async fn find_by_name(&self, name: &str) -> Result<Option<Namespace>>; | ||
} | ||
|
||
pub async fn apply_manifest( | ||
cluster: Arc<dyn ProjectDrivenCluster>, | ||
evt: ProjectCreated, | ||
) -> Result<()> { | ||
if cluster.find_by_name(&evt.namespace).await?.is_some() { | ||
bail!("namespace alread exist") | ||
} | ||
|
||
let namespace = Namespace { | ||
metadata: ObjectMeta { | ||
name: Some(evt.namespace), | ||
..Default::default() | ||
}, | ||
..Default::default() | ||
}; | ||
|
||
cluster.create(&namespace).await?; | ||
|
||
//TODO: create event to update cache | ||
info!(namespace = namespace.name_any(), "new namespace created"); | ||
|
||
Ok(()) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use k8s_openapi::api::core::v1::Namespace; | ||
use mockall::mock; | ||
|
||
use super::*; | ||
|
||
mock! { | ||
pub FakeProjectDrivenCluster { } | ||
|
||
#[async_trait::async_trait] | ||
impl ProjectDrivenCluster for FakeProjectDrivenCluster { | ||
async fn create(&self, namespace: &Namespace) -> Result<()>; | ||
async fn find_by_name(&self, name: &str) -> Result<Option<Namespace>>; | ||
} | ||
} | ||
|
||
#[tokio::test] | ||
async fn it_should_apply_manifest() { | ||
let mut cluster = MockFakeProjectDrivenCluster::new(); | ||
cluster.expect_create().return_once(|_| Ok(())); | ||
cluster.expect_find_by_name().return_once(|_| Ok(None)); | ||
|
||
let project = ProjectCreated::default(); | ||
|
||
let result = apply_manifest(Arc::new(cluster), project).await; | ||
assert!(result.is_ok()); | ||
} | ||
#[tokio::test] | ||
async fn it_should_fail_apply_manifest_when_resource_exists() { | ||
let mut cluster = MockFakeProjectDrivenCluster::new(); | ||
cluster.expect_create().return_once(|_| Ok(())); | ||
cluster | ||
.expect_find_by_name() | ||
.return_once(|_| Ok(Some(Namespace::default()))); | ||
|
||
let project = ProjectCreated::default(); | ||
|
||
let result = apply_manifest(Arc::new(cluster), project).await; | ||
assert!(result.is_err()); | ||
} | ||
} |
Oops, something went wrong.