diff --git a/src/resource/backends/sql.rs b/src/resource/backends/sql.rs index 7ce1abf6..97f65d32 100644 --- a/src/resource/backends/sql.rs +++ b/src/resource/backends/sql.rs @@ -13,18 +13,16 @@ // SPDX-License-Identifier: Apache-2.0 use async_trait::async_trait; -use sea_orm::DatabaseConnection; -use sea_orm::entity::*; -use sea_orm::query::*; -use serde_json::Value; -use tracing::error; + +mod domain; +mod project; use super::super::types::*; use crate::config::Config; -use crate::db::entity::{prelude::Project as DbProject, project as db_project}; use crate::keystone::ServiceState; use crate::resource::ResourceProviderError; -use crate::resource::backends::error::{ResourceDatabaseError, db_err}; +use crate::resource::backends::sql::domain::{get_domain_by_id, get_domain_by_name}; +use crate::resource::backends::sql::project::{get_project, get_project_by_name}; #[derive(Clone, Debug, Default)] pub struct SqlBackend { @@ -78,117 +76,6 @@ impl ResourceBackend for SqlBackend { } } -pub async fn get_domain_by_id>( - _conf: &Config, - db: &DatabaseConnection, - domain_id: I, -) -> Result, ResourceDatabaseError> { - let domain_select = - DbProject::find_by_id(domain_id.as_ref()).filter(db_project::Column::IsDomain.eq(true)); - - let domain_entry: Option = domain_select - .one(db) - .await - .map_err(|err| db_err(err, "fetching domain by id"))?; - domain_entry.map(TryInto::try_into).transpose() -} - -pub async fn get_domain_by_name>( - _conf: &Config, - db: &DatabaseConnection, - domain_name: N, -) -> Result, ResourceDatabaseError> { - let domain_select = DbProject::find() - .filter(db_project::Column::IsDomain.eq(true)) - .filter(db_project::Column::Name.eq(domain_name.as_ref())); - - let domain_entry: Option = domain_select - .one(db) - .await - .map_err(|err| db_err(err, "fetching domain by name"))?; - domain_entry.map(TryInto::try_into).transpose() -} - -pub async fn get_project>( - _conf: &Config, - db: &DatabaseConnection, - id: I, -) -> Result, ResourceDatabaseError> { - let project_select = - DbProject::find_by_id(id.as_ref()).filter(db_project::Column::IsDomain.eq(false)); - - let project_entry: Option = project_select - .one(db) - .await - .map_err(|err| db_err(err, "fetching project by id"))?; - project_entry.map(TryInto::try_into).transpose() -} - -pub async fn get_project_by_name, D: AsRef>( - _conf: &Config, - db: &DatabaseConnection, - name: N, - domain_id: D, -) -> Result, ResourceDatabaseError> { - let project_select = DbProject::find() - .filter(db_project::Column::IsDomain.eq(false)) - .filter(db_project::Column::Name.eq(name.as_ref())) - .filter(db_project::Column::DomainId.eq(domain_id.as_ref())); - - let project_entry: Option = project_select - .one(db) - .await - .map_err(|err| db_err(err, "fetching project by name and domain"))?; - project_entry.map(TryInto::try_into).transpose() -} - -impl TryFrom for Project { - type Error = ResourceDatabaseError; - - fn try_from(value: db_project::Model) -> Result { - let mut project_builder = ProjectBuilder::default(); - project_builder.id(value.id.clone()); - project_builder.name(value.name.clone()); - project_builder.domain_id(value.domain_id.clone()); - if let Some(description) = &value.description { - project_builder.description(description.clone()); - } - project_builder.enabled(value.enabled.unwrap_or(false)); - if let Some(extra) = &value.extra { - project_builder.extra( - serde_json::from_str::(extra) - .inspect_err(|e| error!("failed to deserialize project extra properties: {e}")) - .unwrap_or_default(), - ); - } - - Ok(project_builder.build()?) - } -} - -impl TryFrom for Domain { - type Error = ResourceDatabaseError; - - fn try_from(value: db_project::Model) -> Result { - let mut domain_builder = DomainBuilder::default(); - domain_builder.id(value.id.clone()); - domain_builder.name(value.name.clone()); - if let Some(description) = &value.description { - domain_builder.description(description.clone()); - } - domain_builder.enabled(value.enabled.unwrap_or(false)); - if let Some(extra) = &value.extra { - domain_builder.extra( - serde_json::from_str::(extra) - .inspect_err(|e| error!("failed to deserialize domain extra: {e}")) - .unwrap_or_default(), - ); - } - - Ok(domain_builder.build()?) - } -} - //#[cfg(test)] //mod tests { // #![allow(clippy::derivable_impls)] diff --git a/src/resource/backends/sql/domain/get.rs b/src/resource/backends/sql/domain/get.rs new file mode 100644 index 00000000..4395a001 --- /dev/null +++ b/src/resource/backends/sql/domain/get.rs @@ -0,0 +1,53 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use sea_orm::DatabaseConnection; +use sea_orm::entity::*; +use sea_orm::query::*; + +use crate::db::entity::{prelude::Project as DbProject, project as db_project}; +use crate::resource::Config; +use crate::resource::backends::error::{ResourceDatabaseError, db_err}; +use crate::resource::types::Domain; + +pub async fn get_domain_by_id>( + _conf: &Config, + db: &DatabaseConnection, + domain_id: I, +) -> Result, ResourceDatabaseError> { + let domain_select = + DbProject::find_by_id(domain_id.as_ref()).filter(db_project::Column::IsDomain.eq(true)); + + let domain_entry: Option = domain_select + .one(db) + .await + .map_err(|err| db_err(err, "fetching domain by id"))?; + domain_entry.map(TryInto::try_into).transpose() +} + +pub async fn get_domain_by_name>( + _conf: &Config, + db: &DatabaseConnection, + domain_name: N, +) -> Result, ResourceDatabaseError> { + let domain_select = DbProject::find() + .filter(db_project::Column::IsDomain.eq(true)) + .filter(db_project::Column::Name.eq(domain_name.as_ref())); + + let domain_entry: Option = domain_select + .one(db) + .await + .map_err(|err| db_err(err, "fetching domain by name"))?; + domain_entry.map(TryInto::try_into).transpose() +} diff --git a/src/resource/backends/sql/domain/mod.rs b/src/resource/backends/sql/domain/mod.rs new file mode 100644 index 00000000..eda65a92 --- /dev/null +++ b/src/resource/backends/sql/domain/mod.rs @@ -0,0 +1,48 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +use serde_json::Value; +use tracing::error; + +mod get; + +pub use get::get_domain_by_id; +pub use get::get_domain_by_name; + +use crate::db::entity::project as db_project; +use crate::resource::backends::error::ResourceDatabaseError; +use crate::resource::types::Domain; +use crate::resource::types::DomainBuilder; + +impl TryFrom for Domain { + type Error = ResourceDatabaseError; + + fn try_from(value: db_project::Model) -> Result { + let mut domain_builder = DomainBuilder::default(); + domain_builder.id(value.id.clone()); + domain_builder.name(value.name.clone()); + if let Some(description) = &value.description { + domain_builder.description(description.clone()); + } + domain_builder.enabled(value.enabled.unwrap_or(false)); + if let Some(extra) = &value.extra { + domain_builder.extra( + serde_json::from_str::(extra) + .inspect_err(|e| error!("failed to deserialize domain extra: {e}")) + .unwrap_or_default(), + ); + } + + Ok(domain_builder.build()?) + } +} diff --git a/src/resource/backends/sql/project/get.rs b/src/resource/backends/sql/project/get.rs new file mode 100644 index 00000000..d1bcbf37 --- /dev/null +++ b/src/resource/backends/sql/project/get.rs @@ -0,0 +1,55 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +use sea_orm::DatabaseConnection; +use sea_orm::entity::*; +use sea_orm::query::*; + +use crate::db::entity::{prelude::Project as DbProject, project as db_project}; +use crate::resource::Config; +use crate::resource::backends::error::{ResourceDatabaseError, db_err}; +use crate::resource::types::Project; + +pub async fn get_project>( + _conf: &Config, + db: &DatabaseConnection, + id: I, +) -> Result, ResourceDatabaseError> { + let project_select = + DbProject::find_by_id(id.as_ref()).filter(db_project::Column::IsDomain.eq(false)); + + let project_entry: Option = project_select + .one(db) + .await + .map_err(|err| db_err(err, "fetching project by id"))?; + project_entry.map(TryInto::try_into).transpose() +} + +pub async fn get_project_by_name, D: AsRef>( + _conf: &Config, + db: &DatabaseConnection, + name: N, + domain_id: D, +) -> Result, ResourceDatabaseError> { + let project_select = DbProject::find() + .filter(db_project::Column::IsDomain.eq(false)) + .filter(db_project::Column::Name.eq(name.as_ref())) + .filter(db_project::Column::DomainId.eq(domain_id.as_ref())); + + let project_entry: Option = project_select + .one(db) + .await + .map_err(|err| db_err(err, "fetching project by name and domain"))?; + project_entry.map(TryInto::try_into).transpose() +} diff --git a/src/resource/backends/sql/project/mod.rs b/src/resource/backends/sql/project/mod.rs new file mode 100644 index 00000000..8c7f6b3c --- /dev/null +++ b/src/resource/backends/sql/project/mod.rs @@ -0,0 +1,49 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +use serde_json::Value; +use tracing::error; + +mod get; + +pub use get::get_project; +pub use get::get_project_by_name; + +use crate::db::entity::project as db_project; +use crate::resource::backends::error::ResourceDatabaseError; +use crate::resource::types::Project; +use crate::resource::types::ProjectBuilder; + +impl TryFrom for Project { + type Error = ResourceDatabaseError; + + fn try_from(value: db_project::Model) -> Result { + let mut project_builder = ProjectBuilder::default(); + project_builder.id(value.id.clone()); + project_builder.name(value.name.clone()); + project_builder.domain_id(value.domain_id.clone()); + if let Some(description) = &value.description { + project_builder.description(description.clone()); + } + project_builder.enabled(value.enabled.unwrap_or(false)); + if let Some(extra) = &value.extra { + project_builder.extra( + serde_json::from_str::(extra) + .inspect_err(|e| error!("failed to deserialize project extra properties: {e}")) + .unwrap_or_default(), + ); + } + + Ok(project_builder.build()?) + } +}