From a8dc71fb0407672d72646429014a7c69ce04505c Mon Sep 17 00:00:00 2001 From: oddgrd <29732646+oddgrd@users.noreply.github.com> Date: Sun, 26 Mar 2023 14:10:22 +0200 Subject: [PATCH] feat: commit generated proto files --- proto/Cargo.toml | 2 +- proto/build.rs | 5 - proto/src/generated/provisioner.rs | 382 +++++++++++++++++ proto/src/generated/runtime.rs | 659 +++++++++++++++++++++++++++++ proto/src/lib.rs | 4 +- proto/tests/bootstrap.rs | 34 ++ 6 files changed, 1078 insertions(+), 8 deletions(-) delete mode 100644 proto/build.rs create mode 100644 proto/src/generated/provisioner.rs create mode 100644 proto/src/generated/runtime.rs create mode 100644 proto/tests/bootstrap.rs diff --git a/proto/Cargo.toml b/proto/Cargo.toml index 401cbd2b8..48cf18d84 100644 --- a/proto/Cargo.toml +++ b/proto/Cargo.toml @@ -20,5 +20,5 @@ tracing = { workspace = true } workspace = true features = ["claims", "error", "service", "wasm"] -[build-dependencies] +[dev-dependencies] tonic-build = { workspace = true } diff --git a/proto/build.rs b/proto/build.rs deleted file mode 100644 index 685a01573..000000000 --- a/proto/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() -> Result<(), Box> { - tonic_build::configure().compile(&["./provisioner.proto", "./runtime.proto"], &["./"])?; - - Ok(()) -} diff --git a/proto/src/generated/provisioner.rs b/proto/src/generated/provisioner.rs new file mode 100644 index 000000000..8995c0230 --- /dev/null +++ b/proto/src/generated/provisioner.rs @@ -0,0 +1,382 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseRequest { + #[prost(string, tag = "1")] + pub project_name: ::prost::alloc::string::String, + #[prost(oneof = "database_request::DbType", tags = "10, 11")] + pub db_type: ::core::option::Option, +} +/// Nested message and enum types in `DatabaseRequest`. +pub mod database_request { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum DbType { + #[prost(message, tag = "10")] + Shared(super::Shared), + #[prost(message, tag = "11")] + AwsRds(super::AwsRds), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Shared { + #[prost(oneof = "shared::Engine", tags = "1, 50")] + pub engine: ::core::option::Option, +} +/// Nested message and enum types in `Shared`. +pub mod shared { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Engine { + #[prost(string, tag = "1")] + Postgres(::prost::alloc::string::String), + #[prost(string, tag = "50")] + Mongodb(::prost::alloc::string::String), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AwsRds { + #[prost(oneof = "aws_rds::Engine", tags = "1, 2, 3")] + pub engine: ::core::option::Option, +} +/// Nested message and enum types in `AwsRds`. +pub mod aws_rds { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Engine { + #[prost(message, tag = "1")] + Postgres(super::RdsConfig), + #[prost(message, tag = "2")] + Mysql(super::RdsConfig), + #[prost(message, tag = "3")] + Mariadb(super::RdsConfig), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RdsConfig {} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseResponse { + #[prost(string, tag = "1")] + pub username: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub password: ::prost::alloc::string::String, + #[prost(string, tag = "3")] + pub database_name: ::prost::alloc::string::String, + #[prost(string, tag = "4")] + pub engine: ::prost::alloc::string::String, + #[prost(string, tag = "5")] + pub address_private: ::prost::alloc::string::String, + #[prost(string, tag = "6")] + pub address_public: ::prost::alloc::string::String, + #[prost(string, tag = "7")] + pub port: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DatabaseDeletionResponse {} +/// Generated client implementations. +pub mod provisioner_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct ProvisionerClient { + inner: tonic::client::Grpc, + } + impl ProvisionerClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: std::convert::TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl ProvisionerClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> ProvisionerClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + ProvisionerClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + pub async fn provision_database( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/provisioner.Provisioner/ProvisionDatabase", + ); + self.inner.unary(request.into_request(), path, codec).await + } + pub async fn delete_database( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/provisioner.Provisioner/DeleteDatabase", + ); + self.inner.unary(request.into_request(), path, codec).await + } + } +} +/// Generated server implementations. +pub mod provisioner_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with ProvisionerServer. + #[async_trait] + pub trait Provisioner: Send + Sync + 'static { + async fn provision_database( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + async fn delete_database( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + } + #[derive(Debug)] + pub struct ProvisionerServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + } + struct _Inner(Arc); + impl ProvisionerServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + } + impl tonic::codegen::Service> for ProvisionerServer + where + T: Provisioner, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/provisioner.Provisioner/ProvisionDatabase" => { + #[allow(non_camel_case_types)] + struct ProvisionDatabaseSvc(pub Arc); + impl< + T: Provisioner, + > tonic::server::UnaryService + for ProvisionDatabaseSvc { + type Response = super::DatabaseResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { + (*inner).provision_database(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = ProvisionDatabaseSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/provisioner.Provisioner/DeleteDatabase" => { + #[allow(non_camel_case_types)] + struct DeleteDatabaseSvc(pub Arc); + impl< + T: Provisioner, + > tonic::server::UnaryService + for DeleteDatabaseSvc { + type Response = super::DatabaseDeletionResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { + (*inner).delete_database(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = DeleteDatabaseSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for ProvisionerServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(self.0.clone()) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService for ProvisionerServer { + const NAME: &'static str = "provisioner.Provisioner"; + } +} diff --git a/proto/src/generated/runtime.rs b/proto/src/generated/runtime.rs new file mode 100644 index 000000000..32998af45 --- /dev/null +++ b/proto/src/generated/runtime.rs @@ -0,0 +1,659 @@ +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LoadRequest { + /// Name of service to load + #[prost(string, tag = "1")] + pub service_name: ::prost::alloc::string::String, + /// Path to compiled file to load for service + #[prost(string, tag = "2")] + pub path: ::prost::alloc::string::String, + /// A cache of resource details to use instead when asked + #[prost(bytes = "vec", repeated, tag = "10")] + pub resources: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + /// Secrets that belong to this deployment + #[prost(map = "string, string", tag = "20")] + pub secrets: ::std::collections::HashMap< + ::prost::alloc::string::String, + ::prost::alloc::string::String, + >, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LoadResponse { + /// Could the service be loaded + #[prost(bool, tag = "1")] + pub success: bool, + /// Error message if not successful + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, + /// Which resources where requested + #[prost(bytes = "vec", repeated, tag = "10")] + pub resources: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StartRequest { + /// Address and port to start the service on + #[prost(string, tag = "1")] + pub ip: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StartResponse { + /// Was the start successful + #[prost(bool, tag = "1")] + pub success: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StopRequest {} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct StopResponse { + /// Was the stop successful + #[prost(bool, tag = "1")] + pub success: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SubscribeStopRequest {} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SubscribeStopResponse { + /// Reason the service has stopped + #[prost(enumeration = "StopReason", tag = "1")] + pub reason: i32, + /// Any extra message to go with the reason. If there are any + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SubscribeLogsRequest {} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LogItem { + #[prost(message, optional, tag = "2")] + pub timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(enumeration = "LogLevel", tag = "4")] + pub level: i32, + #[prost(string, optional, tag = "5")] + pub file: ::core::option::Option<::prost::alloc::string::String>, + #[prost(uint32, optional, tag = "6")] + pub line: ::core::option::Option, + #[prost(string, tag = "7")] + pub target: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "8")] + pub fields: ::prost::alloc::vec::Vec, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum StopReason { + /// User requested this stop + Request = 0, + /// Service stopped by itself + End = 1, + /// Service crashed + Crash = 2, +} +impl StopReason { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + StopReason::Request => "Request", + StopReason::End => "End", + StopReason::Crash => "Crash", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Request" => Some(Self::Request), + "End" => Some(Self::End), + "Crash" => Some(Self::Crash), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum LogLevel { + Trace = 0, + Debug = 1, + Info = 2, + Warn = 3, + Error = 4, +} +impl LogLevel { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + LogLevel::Trace => "Trace", + LogLevel::Debug => "Debug", + LogLevel::Info => "Info", + LogLevel::Warn => "Warn", + LogLevel::Error => "Error", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "Trace" => Some(Self::Trace), + "Debug" => Some(Self::Debug), + "Info" => Some(Self::Info), + "Warn" => Some(Self::Warn), + "Error" => Some(Self::Error), + _ => None, + } + } +} +/// Generated client implementations. +pub mod runtime_client { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + use tonic::codegen::http::Uri; + #[derive(Debug, Clone)] + pub struct RuntimeClient { + inner: tonic::client::Grpc, + } + impl RuntimeClient { + /// Attempt to create a new client by connecting to a given endpoint. + pub async fn connect(dst: D) -> Result + where + D: std::convert::TryInto, + D::Error: Into, + { + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; + Ok(Self::new(conn)) + } + } + impl RuntimeClient + where + T: tonic::client::GrpcService, + T::Error: Into, + T::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, + { + pub fn new(inner: T) -> Self { + let inner = tonic::client::Grpc::new(inner); + Self { inner } + } + pub fn with_origin(inner: T, origin: Uri) -> Self { + let inner = tonic::client::Grpc::with_origin(inner, origin); + Self { inner } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> RuntimeClient> + where + F: tonic::service::Interceptor, + T::ResponseBody: Default, + T: tonic::codegen::Service< + http::Request, + Response = http::Response< + >::ResponseBody, + >, + >, + , + >>::Error: Into + Send + Sync, + { + RuntimeClient::new(InterceptedService::new(inner, interceptor)) + } + /// Compress requests with the given encoding. + /// + /// This requires the server to support it otherwise it might respond with an + /// error. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.send_compressed(encoding); + self + } + /// Enable decompressing responses. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.inner = self.inner.accept_compressed(encoding); + self + } + /// Load a service file to be ready to start it + pub async fn load( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/runtime.Runtime/Load"); + self.inner.unary(request.into_request(), path, codec).await + } + /// Start a loaded service file + pub async fn start( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/runtime.Runtime/Start"); + self.inner.unary(request.into_request(), path, codec).await + } + /// Stop a started service + pub async fn stop( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result, tonic::Status> { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static("/runtime.Runtime/Stop"); + self.inner.unary(request.into_request(), path, codec).await + } + /// Channel to notify a service has been stopped + pub async fn subscribe_stop( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/runtime.Runtime/SubscribeStop", + ); + self.inner.server_streaming(request.into_request(), path, codec).await + } + /// Subscribe to runtime logs + pub async fn subscribe_logs( + &mut self, + request: impl tonic::IntoRequest, + ) -> Result< + tonic::Response>, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/runtime.Runtime/SubscribeLogs", + ); + self.inner.server_streaming(request.into_request(), path, codec).await + } + } +} +/// Generated server implementations. +pub mod runtime_server { + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] + use tonic::codegen::*; + /// Generated trait containing gRPC methods that should be implemented for use with RuntimeServer. + #[async_trait] + pub trait Runtime: Send + Sync + 'static { + /// Load a service file to be ready to start it + async fn load( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + /// Start a loaded service file + async fn start( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + /// Stop a started service + async fn stop( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + /// Server streaming response type for the SubscribeStop method. + type SubscribeStopStream: futures_core::Stream< + Item = Result, + > + + Send + + 'static; + /// Channel to notify a service has been stopped + async fn subscribe_stop( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + /// Server streaming response type for the SubscribeLogs method. + type SubscribeLogsStream: futures_core::Stream< + Item = Result, + > + + Send + + 'static; + /// Subscribe to runtime logs + async fn subscribe_logs( + &self, + request: tonic::Request, + ) -> Result, tonic::Status>; + } + #[derive(Debug)] + pub struct RuntimeServer { + inner: _Inner, + accept_compression_encodings: EnabledCompressionEncodings, + send_compression_encodings: EnabledCompressionEncodings, + } + struct _Inner(Arc); + impl RuntimeServer { + pub fn new(inner: T) -> Self { + Self::from_arc(Arc::new(inner)) + } + pub fn from_arc(inner: Arc) -> Self { + let inner = _Inner(inner); + Self { + inner, + accept_compression_encodings: Default::default(), + send_compression_encodings: Default::default(), + } + } + pub fn with_interceptor( + inner: T, + interceptor: F, + ) -> InterceptedService + where + F: tonic::service::Interceptor, + { + InterceptedService::new(Self::new(inner), interceptor) + } + /// Enable decompressing requests with the given encoding. + #[must_use] + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.accept_compression_encodings.enable(encoding); + self + } + /// Compress responses with the given encoding, if the client supports it. + #[must_use] + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { + self.send_compression_encodings.enable(encoding); + self + } + } + impl tonic::codegen::Service> for RuntimeServer + where + T: Runtime, + B: Body + Send + 'static, + B::Error: Into + Send + 'static, + { + type Response = http::Response; + type Error = std::convert::Infallible; + type Future = BoxFuture; + fn poll_ready( + &mut self, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + fn call(&mut self, req: http::Request) -> Self::Future { + let inner = self.inner.clone(); + match req.uri().path() { + "/runtime.Runtime/Load" => { + #[allow(non_camel_case_types)] + struct LoadSvc(pub Arc); + impl tonic::server::UnaryService + for LoadSvc { + type Response = super::LoadResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { (*inner).load(request).await }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = LoadSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/runtime.Runtime/Start" => { + #[allow(non_camel_case_types)] + struct StartSvc(pub Arc); + impl tonic::server::UnaryService + for StartSvc { + type Response = super::StartResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { (*inner).start(request).await }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StartSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/runtime.Runtime/Stop" => { + #[allow(non_camel_case_types)] + struct StopSvc(pub Arc); + impl tonic::server::UnaryService + for StopSvc { + type Response = super::StopResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { (*inner).stop(request).await }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = StopSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/runtime.Runtime/SubscribeStop" => { + #[allow(non_camel_case_types)] + struct SubscribeStopSvc(pub Arc); + impl< + T: Runtime, + > tonic::server::ServerStreamingService + for SubscribeStopSvc { + type Response = super::SubscribeStopResponse; + type ResponseStream = T::SubscribeStopStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { + (*inner).subscribe_stop(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = SubscribeStopSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + "/runtime.Runtime/SubscribeLogs" => { + #[allow(non_camel_case_types)] + struct SubscribeLogsSvc(pub Arc); + impl< + T: Runtime, + > tonic::server::ServerStreamingService + for SubscribeLogsSvc { + type Response = super::LogItem; + type ResponseStream = T::SubscribeLogsStream; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = self.0.clone(); + let fut = async move { + (*inner).subscribe_logs(request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let inner = self.inner.clone(); + let fut = async move { + let inner = inner.0; + let method = SubscribeLogsSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ); + let res = grpc.server_streaming(method, req).await; + Ok(res) + }; + Box::pin(fut) + } + _ => { + Box::pin(async move { + Ok( + http::Response::builder() + .status(200) + .header("grpc-status", "12") + .header("content-type", "application/grpc") + .body(empty_body()) + .unwrap(), + ) + }) + } + } + } + } + impl Clone for RuntimeServer { + fn clone(&self) -> Self { + let inner = self.inner.clone(); + Self { + inner, + accept_compression_encodings: self.accept_compression_encodings, + send_compression_encodings: self.send_compression_encodings, + } + } + } + impl Clone for _Inner { + fn clone(&self) -> Self { + Self(self.0.clone()) + } + } + impl std::fmt::Debug for _Inner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self.0) + } + } + impl tonic::server::NamedService for RuntimeServer { + const NAME: &'static str = "runtime.Runtime"; + } +} diff --git a/proto/src/lib.rs b/proto/src/lib.rs index 6f8602591..596e45296 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -10,7 +10,7 @@ pub mod provisioner { DatabaseReadyInfo, }; - tonic::include_proto!("provisioner"); + include!("generated/provisioner.rs"); impl From for DatabaseReadyInfo { fn from(response: DatabaseResponse) -> Self { @@ -118,7 +118,7 @@ pub mod runtime { WorkingDir(PathBuf), } - tonic::include_proto!("runtime"); + include!("generated/runtime.rs"); impl From for LogLevel { fn from(level: shuttle_common::log::Level) -> Self { diff --git a/proto/tests/bootstrap.rs b/proto/tests/bootstrap.rs new file mode 100644 index 000000000..ce0e97ce1 --- /dev/null +++ b/proto/tests/bootstrap.rs @@ -0,0 +1,34 @@ +use std::{path::PathBuf, process::Command}; + +// This test will compile the `.proto` files and put the generated code +// in `src/generated`. We commit the generated code, and run this test in +// CI to make sure that the generated files are up to date with any changes +// to the `.proto` files. +#[test] +fn bootstrap() { + let proto_files = &["provisioner.proto", "runtime.proto"]; + + let out_dir = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")) + .join("src") + .join("generated"); + + tonic_build::configure() + .out_dir(format!("{}", out_dir.display())) + .compile(proto_files, &["./"]) + .unwrap(); + + let status = Command::new("git") + .arg("diff") + .arg("--exit-code") + .arg("--") + .arg(format!("{}", out_dir.display())) + .status() + .unwrap(); + + if !status.success() { + panic!("You should commit the protobuf files"); + } +} + +// This solution is based on this tonic-health pull request: +// https://github.com/hyperium/tonic/pull/1065/