From 94c65bf8be49aa1070870c6e9297d8c792657db2 Mon Sep 17 00:00:00 2001 From: Nico Burniske Date: Wed, 27 Mar 2024 15:18:37 -0400 Subject: [PATCH] remove namespace first part --- golem-service-base/src/model.rs | 28 + golem-worker-service-base/src/api/common.rs | 7 - golem-worker-service-base/src/auth.rs | 47 +- .../src/service/api_definition.rs | 208 ++++---- golem-worker-service-base/src/service/mod.rs | 20 + .../src/service/template/default.rs | 96 ++-- .../src/service/worker/default.rs | 492 +++++++----------- golem-worker-service/src/api/mod.rs | 1 - .../src/api/register_api_definition_api.rs | 60 +-- golem-worker-service/src/api/worker.rs | 32 +- .../src/api/worker_connect.rs | 6 +- golem-worker-service/src/grpcapi/worker.rs | 39 +- golem-worker-service/src/lib.rs | 11 + golem-worker-service/src/service/mod.rs | 34 +- golem-worker-service/src/service/template.rs | 38 +- golem-worker-service/src/service/worker.rs | 9 +- .../src/worker_request_to_http_response.rs | 17 +- 17 files changed, 481 insertions(+), 664 deletions(-) diff --git a/golem-service-base/src/model.rs b/golem-service-base/src/model.rs index 19ee0e128..292470e4b 100644 --- a/golem-service-base/src/model.rs +++ b/golem-service-base/src/model.rs @@ -3116,3 +3116,31 @@ impl From for RoutingTableEntry { } } } + +#[derive( + Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, serde::Serialize, serde::Deserialize, Object, +)] +#[serde(rename_all = "camelCase")] +#[oai(rename_all = "camelCase")] +pub struct ResourceLimits { + pub available_fuel: i64, + pub max_memory_per_worker: i64, +} + +impl From for golem_api_grpc::proto::golem::common::ResourceLimits { + fn from(value: ResourceLimits) -> Self { + Self { + available_fuel: value.available_fuel, + max_memory_per_worker: value.max_memory_per_worker, + } + } +} + +impl From for ResourceLimits { + fn from(value: golem_api_grpc::proto::golem::common::ResourceLimits) -> Self { + Self { + available_fuel: value.available_fuel, + max_memory_per_worker: value.max_memory_per_worker, + } + } +} diff --git a/golem-worker-service-base/src/api/common.rs b/golem-worker-service-base/src/api/common.rs index 76c9ffd26..2faa20e61 100644 --- a/golem-worker-service-base/src/api/common.rs +++ b/golem-worker-service-base/src/api/common.rs @@ -99,7 +99,6 @@ impl ApiEndpointError { } mod conversion { - use golem_service_base::service::auth::AuthError; use poem_openapi::payload::Json; use super::{ @@ -112,12 +111,6 @@ mod conversion { impl From for ApiEndpointError { fn from(error: ApiRegistrationError) -> Self { match error { - ApiRegistrationError::AuthenticationError(auth) => match auth { - AuthError::Forbidden(_) => ApiEndpointError::forbidden(auth), - AuthError::Unauthorized(_) => ApiEndpointError::unauthorized(auth), - AuthError::Internal(_) => ApiEndpointError::internal(auth), - AuthError::NotFound(_) => ApiEndpointError::not_found(auth), - }, ApiRegistrationError::RepoError(error) => match error { ApiRegistrationRepoError::AlreadyExists(_) => { ApiEndpointError::already_exists(error) diff --git a/golem-worker-service-base/src/auth.rs b/golem-worker-service-base/src/auth.rs index b6c2086ea..dd23023a3 100644 --- a/golem-worker-service-base/src/auth.rs +++ b/golem-worker-service-base/src/auth.rs @@ -1,12 +1,7 @@ use std::fmt::{Display, Formatter}; -use async_trait::async_trait; -use golem_api_grpc::proto::golem::common::ResourceLimits; -use golem_common::model::AccountId; -use golem_service_base::service::auth::{AuthError, AuthService, Permission}; use serde::Deserialize; -pub struct AuthServiceNoop {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EmptyAuthCtx {} @@ -16,6 +11,15 @@ impl Display for EmptyAuthCtx { } } +impl IntoIterator for EmptyAuthCtx { + type Item = (String, String); + type IntoIter = std::iter::Empty; + + fn into_iter(self) -> Self::IntoIter { + std::iter::empty() + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash, bincode::Encode, bincode::Decode, Deserialize)] pub struct CommonNamespace(String); @@ -30,36 +34,3 @@ impl Display for CommonNamespace { write!(f, "{}", self.0) } } - -#[async_trait] -impl AuthService for AuthServiceNoop { - async fn is_authorized( - &self, - _permission: Permission, - _ctx: &AuthCtx, - ) -> Result { - Ok(Namespace::default()) - } -} - -// TODO: Replace with metadata map -pub trait HasMetadata { - fn get_metadata(&self) -> WorkerMetadata; -} - -#[derive(Clone, Debug)] -pub struct WorkerMetadata { - pub account_id: Option, - pub limits: Option, -} - -impl HasMetadata for CommonNamespace { - fn get_metadata(&self) -> WorkerMetadata { - WorkerMetadata { - account_id: Some(golem_common::model::AccountId { - value: "-1".to_string(), - }), - limits: None, - } - } -} diff --git a/golem-worker-service-base/src/service/api_definition.rs b/golem-worker-service-base/src/service/api_definition.rs index 3fd6b5eba..f8c88c7c1 100644 --- a/golem-worker-service-base/src/service/api_definition.rs +++ b/golem-worker-service-base/src/service/api_definition.rs @@ -5,15 +5,13 @@ use std::sync::Arc; use crate::api_definition::{ApiDefinition, ApiDefinitionId, Version}; use crate::api_definition_repo::{ApiDefinitionRepo, ApiRegistrationRepoError}; -use crate::auth::{CommonNamespace, EmptyAuthCtx}; use async_trait::async_trait; use golem_service_base::model::Template; -use golem_service_base::service::auth::{AuthError, AuthService, Permission, WithNamespace}; use super::api_definition_validator::{ApiDefinitionValidatorService, ValidationError}; use super::template::TemplateService; -pub type ApiResult = Result, ApiRegistrationError>; +pub type ApiResult = Result; // A namespace here can be example: (account, project) etc. // Ideally a repo service and its implementation with a different service impl that takes care of @@ -23,30 +21,38 @@ pub trait ApiDefinitionService { async fn register( &self, definition: &ApiDefinition, - auth_ctx: AuthCtx, - ) -> ApiResult; + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult; async fn get( &self, api_definition_id: &ApiDefinitionId, version: &Version, - auth_ctx: AuthCtx, - ) -> ApiResult, Namespace>; + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult>; async fn delete( &self, api_definition_id: &ApiDefinitionId, version: &Version, - auth_ctx: AuthCtx, - ) -> ApiResult, Namespace>; + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult>; - async fn get_all(&self, auth_ctx: AuthCtx) -> ApiResult, Namespace>; + async fn get_all( + &self, + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult>; async fn get_all_versions( &self, api_id: &ApiDefinitionId, - auth_ctx: AuthCtx, - ) -> ApiResult, Namespace>; + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult>; } pub trait ApiNamespace: @@ -104,53 +110,34 @@ impl ApiDefinitionKey { #[derive(Debug, Clone, thiserror::Error)] pub enum ApiRegistrationError { - #[error(transparent)] - AuthenticationError(#[from] AuthError), #[error(transparent)] RepoError(#[from] ApiRegistrationRepoError), #[error(transparent)] ValidationError(#[from] ValidationError), } -pub struct RegisterApiDefinitionDefault { - pub template_service: Arc + Send + Sync>, - pub auth_service: Arc + Sync + Send>, - pub register_repo: Arc + Sync + Send>, +pub struct RegisterApiDefinitionDefault { + pub template_service: Arc + Send + Sync>, + pub register_repo: Arc + Sync + Send>, pub api_definition_validator: Arc, } -impl - RegisterApiDefinitionDefault +impl RegisterApiDefinitionDefault where - AuthCtx: Send + Sync, - ApiDefNamespace: ApiNamespace, - TemplateNamespace: std::fmt::Debug + Send + Sync, + Namespace: ApiNamespace + Send + Sync, { pub fn new( - template_service: Arc + Send + Sync>, - auth_service: Arc + Sync + Send>, - register_repo: Arc + Sync + Send>, + template_service: Arc + Send + Sync>, + register_repo: Arc + Sync + Send>, api_definition_validator: Arc, ) -> Self { Self { template_service, - auth_service, register_repo, api_definition_validator, } } - pub async fn is_authorized( - &self, - permission: Permission, - auth_ctx: &AuthCtx, - ) -> Result { - Ok(self - .auth_service - .is_authorized(permission, auth_ctx) - .await?) - } - async fn get_all_templates( &self, definition: &ApiDefinition, @@ -163,19 +150,18 @@ where .map(|route| (route.binding.template.clone(), route)) .collect::>() .into_values() - .map(|route| async move { - let id = &route.binding.template; - self.template_service - .get_latest(id, auth_ctx) - .await - .map_err(|e| { - tracing::error!("Error getting latest template: {:?}", e); - // TODO: Better error message. - crate::service::api_definition_validator::RouteValidationError::from_route( - route, - "Error getting latest template".into(), - ) - }) + .map(|route| { + async move { + let id = &route.binding.template; + self.template_service.get_latest(id, auth_ctx).await.map_err(|e| { + tracing::error!("Error getting latest template: {:?}", e); + // TODO: Better error message. + crate::service::api_definition_validator::RouteValidationError::from_route( + route, + "Error getting latest template".into(), + ) + }) + } }) .collect::>(); @@ -191,11 +177,7 @@ where return Err(ValidationError { errors }.into()); } - successes - .into_iter() - .map(|r| r.unwrap()) - .map(|t| t.value) - .collect() + successes.into_iter().map(|r| r.unwrap()).collect() }; Ok(templates) @@ -203,21 +185,19 @@ where } #[async_trait] -impl ApiDefinitionService - for RegisterApiDefinitionDefault +impl ApiDefinitionService + for RegisterApiDefinitionDefault where AuthCtx: Send + Sync, - ApiDefNamespace: ApiNamespace, - TemplateNamespace: std::fmt::Debug + Send + Sync, + Namespace: ApiNamespace + Send + Sync, { async fn register( &self, definition: &ApiDefinition, - auth_ctx: AuthCtx, - ) -> ApiResult { - let namespace = self.is_authorized(Permission::Create, &auth_ctx).await?; - - let templates = self.get_all_templates(definition, &auth_ctx).await?; + namespace: Namespace, + auth_ctx: &AuthCtx, + ) -> ApiResult { + let templates = self.get_all_templates(definition, auth_ctx).await?; self.api_definition_validator .validate(definition, templates.as_slice())?; @@ -230,20 +210,16 @@ where self.register_repo.register(definition, &key).await?; - Ok(WithNamespace { - value: key.id, - namespace, - }) + Ok(key.id) } async fn get( &self, api_definition_id: &ApiDefinitionId, version: &Version, - auth_ctx: AuthCtx, - ) -> ApiResult, ApiDefNamespace> { - let namespace = self.is_authorized(Permission::View, &auth_ctx).await?; - + namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { let key = ApiDefinitionKey { namespace: namespace.clone(), id: api_definition_id.clone(), @@ -252,17 +228,16 @@ where let value = self.register_repo.get(&key).await?; - Ok(WithNamespace { value, namespace }) + Ok(value) } async fn delete( &self, api_definition_id: &ApiDefinitionId, version: &Version, - auth_ctx: AuthCtx, - ) -> ApiResult, ApiDefNamespace> { - let namespace = self.is_authorized(Permission::Delete, &auth_ctx).await?; - + namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { let key = ApiDefinitionKey { namespace: namespace.clone(), id: api_definition_id.clone(), @@ -273,88 +248,83 @@ where let value = if deleted { Some(key.id) } else { None }; - Ok(WithNamespace { value, namespace }) + Ok(value) } - async fn get_all(&self, auth_ctx: AuthCtx) -> ApiResult, ApiDefNamespace> { - let namespace = self.is_authorized(Permission::View, &auth_ctx).await?; + async fn get_all( + &self, + namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { let value = self.register_repo.get_all(&namespace).await?; - Ok(WithNamespace { value, namespace }) + Ok(value) } async fn get_all_versions( &self, api_id: &ApiDefinitionId, - auth_ctx: AuthCtx, - ) -> ApiResult, ApiDefNamespace> { - let namespace = self.is_authorized(Permission::View, &auth_ctx).await?; - + namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { let value = self .register_repo .get_all_versions(api_id, &namespace) .await?; - Ok(WithNamespace { value, namespace }) + Ok(value) } } pub struct RegisterApiDefinitionNoop {} #[async_trait] -impl ApiDefinitionService for RegisterApiDefinitionNoop { +impl ApiDefinitionService for RegisterApiDefinitionNoop +where + Namespace: Default + Send + Sync + 'static, +{ async fn register( &self, - api_definition: &ApiDefinition, - _auth_ctx: EmptyAuthCtx, - ) -> ApiResult { - Ok(WithNamespace { - value: api_definition.id.clone(), - namespace: Default::default(), - }) + _definition: &ApiDefinition, + _namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult { + Ok(ApiDefinitionId("noop".to_string())) } async fn get( &self, _api_definition_id: &ApiDefinitionId, _version: &Version, - _auth_ctx: EmptyAuthCtx, - ) -> ApiResult, CommonNamespace> { - Ok(WithNamespace { - value: None, - namespace: Default::default(), - }) + _namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { + Ok(None) } async fn delete( &self, _api_definition_id: &ApiDefinitionId, _version: &Version, - _auth_ctx: EmptyAuthCtx, - ) -> ApiResult, CommonNamespace> { - Ok(WithNamespace { - value: None, - namespace: Default::default(), - }) + _namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { + Ok(None) } async fn get_all( &self, - _auth_ctx: EmptyAuthCtx, - ) -> ApiResult, CommonNamespace> { - Ok(WithNamespace { - value: vec![], - namespace: Default::default(), - }) + _namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { + Ok(vec![]) } async fn get_all_versions( &self, _api_id: &ApiDefinitionId, - _auth_ctx: EmptyAuthCtx, - ) -> ApiResult, CommonNamespace> { - Ok(WithNamespace { - value: vec![], - namespace: Default::default(), - }) + _namespace: Namespace, + _auth_ctx: &AuthCtx, + ) -> ApiResult> { + Ok(vec![]) } } diff --git a/golem-worker-service-base/src/service/mod.rs b/golem-worker-service-base/src/service/mod.rs index 7cb60bf97..641a7e1cd 100644 --- a/golem-worker-service-base/src/service/mod.rs +++ b/golem-worker-service-base/src/service/mod.rs @@ -3,3 +3,23 @@ pub mod api_definition_validator; pub mod http_request_definition_lookup; pub mod template; pub mod worker; + +pub fn with_metadata(request: T, metadata: I) -> tonic::Request +where + I: IntoIterator, + K: AsRef, + V: AsRef, +{ + let mut req = tonic::Request::new(request); + let req_metadata = req.metadata_mut(); + + for (key, value) in metadata { + let key = tonic::metadata::MetadataKey::from_bytes(key.as_ref().as_bytes()); + let value = value.as_ref().parse(); + if let (Ok(key), Ok(value)) = (key, value) { + req_metadata.insert(key, value); + } + } + + req +} diff --git a/golem-worker-service-base/src/service/template/default.rs b/golem-worker-service-base/src/service/template/default.rs index 5686241c2..147cc278b 100644 --- a/golem-worker-service-base/src/service/template/default.rs +++ b/golem-worker-service-base/src/service/template/default.rs @@ -1,4 +1,5 @@ use crate::service::template::TemplateServiceError; +use crate::service::with_metadata; use crate::UriBackConversion; use async_trait::async_trait; @@ -10,86 +11,65 @@ use golem_common::config::RetryConfig; use golem_common::model::TemplateId; use golem_common::retries::with_retries; use golem_service_base::model::Template; -use golem_service_base::service::auth::{AuthService, Permission, WithAuth, WithNamespace}; use http::Uri; -use std::sync::Arc; use tracing::info; -pub type TemplateResult = Result, TemplateServiceError>; +pub type TemplateResult = Result; #[async_trait] -pub trait TemplateService { +pub trait TemplateService { async fn get_by_version( &self, template_id: &TemplateId, version: i32, auth_ctx: &AuthCtx, - ) -> TemplateResult; + ) -> TemplateResult