diff --git a/dozer-cli/src/cli/helper.rs b/dozer-cli/src/cli/helper.rs index d9f2eae2d9..d0cd28bc89 100644 --- a/dozer-cli/src/cli/helper.rs +++ b/dozer-cli/src/cli/helper.rs @@ -38,15 +38,18 @@ pub async fn init_config( Ok(config) } +pub fn get_base_dir() -> Result { + let base_directory = std::env::current_dir().map_err(CliError::Io)?; + + Utf8PathBuf::try_from(base_directory).map_err(|e| CliError::Io(e.into_io_error())) +} + pub fn init_dozer( runtime: Arc, config: Config, labels: LabelsAndProgress, ) -> Result { - let base_directory = std::env::current_dir().map_err(CliError::Io)?; - let base_directory = - Utf8PathBuf::try_from(base_directory).map_err(|e| CliError::Io(e.into_io_error()))?; - + let base_directory = get_base_dir()?; Ok(Dozer::new(base_directory, config, runtime, labels)) } diff --git a/dozer-cli/src/cli/mod.rs b/dozer-cli/src/cli/mod.rs index f32621d071..2c12a2e307 100644 --- a/dozer-cli/src/cli/mod.rs +++ b/dozer-cli/src/cli/mod.rs @@ -4,5 +4,7 @@ mod helper; mod init; pub mod types; -pub use helper::{init_config, init_dozer, list_sources, load_config_from_file, LOGO}; +pub use helper::{ + get_base_dir, init_config, init_dozer, list_sources, load_config_from_file, LOGO, +}; pub use init::{generate_config_repl, generate_connection}; diff --git a/dozer-cli/src/cloud/client.rs b/dozer-cli/src/cloud/client.rs index 6052b0e91c..2392a9cde5 100644 --- a/dozer-cli/src/cloud/client.rs +++ b/dozer-cli/src/cloud/client.rs @@ -1,7 +1,7 @@ use crate::cli::cloud::{ Cloud, DeployCommandArgs, ListCommandArgs, LogCommandArgs, SecretsCommand, VersionCommand, }; -use crate::cli::init_dozer; +use crate::cli::get_base_dir; use crate::cloud::cloud_app_context::CloudAppContext; use crate::cloud::cloud_helper::list_files; @@ -13,8 +13,9 @@ use crate::cloud::DozerGrpcCloudClient; use crate::console_helper::{get_colored_text, PURPLE}; use crate::errors::OrchestrationError::FailedToReadOrganisationName; use crate::errors::{ - map_tonic_error, CliError, CloudError, CloudLoginError, ConfigCombineError, OrchestrationError, + map_tonic_error, CliError, CloudContextError, CloudError, CloudLoginError, OrchestrationError, }; +use crate::simple::orchestrator::lockfile_path; use dozer_types::constants::{DEFAULT_CLOUD_TARGET_URL, LOCK_FILE}; use dozer_types::grpc_types::api_explorer::api_explorer_service_client::ApiExplorerServiceClient; use dozer_types::grpc_types::api_explorer::GetApiTokenRequest; @@ -33,17 +34,16 @@ use dozer_types::prettytable::{row, table}; use futures::{select, FutureExt, StreamExt}; use std::io; use std::sync::Arc; -use tokio::runtime::Runtime; use tonic::transport::Endpoint; use tower::ServiceBuilder; use super::login::LoginSvc; async fn establish_cloud_service_channel( cloud: &Cloud, - cloud_config: &dozer_types::models::cloud::Cloud, + cloud_config: Option, ) -> Result { - let profile_name = match &cloud.profile { - None => cloud_config.profile.clone(), + let profile_name = match cloud.profile.as_ref() { + None => cloud_config.as_ref().and_then(|f| f.profile.clone()), Some(_) => cloud.profile.clone(), }; let credential = CredentialInfo::load(profile_name)?; @@ -63,7 +63,7 @@ async fn establish_cloud_service_channel( pub async fn get_grpc_cloud_client( cloud: &Cloud, - cloud_config: &dozer_types::models::cloud::Cloud, + cloud_config: Option, ) -> Result, CloudError> { let client = DozerCloudClient::new(establish_cloud_service_channel(cloud, cloud_config).await?); Ok(client) @@ -71,7 +71,7 @@ pub async fn get_grpc_cloud_client( pub async fn get_explorer_client( cloud: &Cloud, - cloud_config: &dozer_types::models::cloud::Cloud, + cloud_config: Option, ) -> Result, CloudError> { let client = ApiExplorerServiceClient::new(establish_cloud_service_channel(cloud, cloud_config).await?); @@ -79,14 +79,32 @@ pub async fn get_explorer_client( } pub struct CloudClient { - config: Config, + config: Option, runtime: Arc, } impl CloudClient { - pub fn new(config: Config, runtime: Arc) -> Self { + pub fn new(config: Option, runtime: Arc) -> Self { Self { config, runtime } } + + pub fn get_app_id(&self) -> Option<(String, bool)> { + // Get app_id from command line argument if there, otherwise take it from the cloud config file + // if the app_id is from the cloud config file then set `from_cloud_file` to true and use it later + // to perform cleanup in case of delete and other operations + + self.config.as_ref().and_then(|config| { + config.cloud.app_id.clone().map(|app_id| (app_id, true)).or( + CloudAppContext::get_app_id(&config.cloud) + .ok() + .map(|app_id| (app_id, false)), + ) + }) + } + + fn get_cloud_config(&self) -> Option { + self.config.as_ref().map(|config| config.cloud.clone()) + } } impl DozerGrpcCloudClient for CloudClient { @@ -97,19 +115,12 @@ impl DozerGrpcCloudClient for CloudClient { deploy: DeployCommandArgs, config_paths: Vec, ) -> Result<(), OrchestrationError> { - let app_id = cloud - .app_id - .clone() - .or(CloudAppContext::get_app_id(&self.config.cloud).ok()); - - let dozer = init_dozer( - self.runtime.clone(), - self.config.clone(), - Default::default(), - )?; - let lockfile_path = dozer.lockfile_path(); + let app_id = self.get_app_id().map(|a| a.0); + + let base_dir = get_base_dir()?; + let lockfile_path = lockfile_path(base_dir); self.runtime.clone().block_on(async move { - let mut client = get_grpc_cloud_client(&cloud, &self.config.cloud).await?; + let mut client = get_grpc_cloud_client(&cloud, self.get_cloud_config()).await?; let mut files = list_files(config_paths)?; if deploy.locked { let lockfile_contents = tokio::fs::read_to_string(lockfile_path) @@ -143,23 +154,38 @@ impl DozerGrpcCloudClient for CloudClient { })?; Ok(()) } + fn create( + &mut self, + cloud: Cloud, + config_paths: Vec, + ) -> Result<(), OrchestrationError> { + let cloud_config = self.get_cloud_config(); + let app_id = self.get_app_id().map(|a| a.0); - fn delete(&mut self, cloud: Cloud) -> Result<(), OrchestrationError> { - // Get app_id from command line argument if there, otherwise take it from the cloud config file - // if the app_id is from the cloud config file then set `delete_cloud_file` to true and use it later - // to delete the file after deleting the app - - let (app_id, delete_cloud_file) = if let Some(app_id) = cloud.app_id.clone() { - // if the app_id on command line is equal to the one in the cloud config file then file can be deleted - if app_id == CloudAppContext::get_app_id(&self.config.cloud)? { - (app_id, true) - } else { - (app_id, false) - } - } else { - (CloudAppContext::get_app_id(&self.config.cloud)?, true) + if let Some(app_id) = app_id { + return Err(CloudContextError::AppIdAlreadyExists(app_id).into()); }; + self.runtime.block_on(async move { + let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; + let files = list_files(config_paths)?; + let response = client + .create_application(CreateAppRequest { files }) + .await + .map_err(map_tonic_error)? + .into_inner(); + + CloudAppContext::save_app_id(response.app_id.clone())?; + info!("Application created with id {}", response.app_id); + Ok::<(), OrchestrationError>(()) + }) + } + + fn delete(&mut self, cloud: Cloud) -> Result<(), OrchestrationError> { + let (app_id, delete_cloud_file) = self + .get_app_id() + .ok_or_else(|| CloudContextError::AppIdNotFound)?; + let mut double_check = String::new(); println!("Are you sure to delete the application {}? (y/N)", app_id); io::stdin() @@ -174,7 +200,7 @@ impl DozerGrpcCloudClient for CloudClient { return Ok(()); } - let cloud_config = &self.config.cloud; + let cloud_config = self.get_cloud_config(); self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; @@ -201,7 +227,7 @@ impl DozerGrpcCloudClient for CloudClient { } fn list(&mut self, cloud: Cloud, list: ListCommandArgs) -> Result<(), OrchestrationError> { - let cloud_config = &self.config.cloud; + let cloud_config = self.get_cloud_config(); self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; let response = client @@ -239,11 +265,11 @@ impl DozerGrpcCloudClient for CloudClient { } fn status(&mut self, cloud: Cloud) -> Result<(), OrchestrationError> { - let app_id = cloud - .app_id - .clone() - .unwrap_or(CloudAppContext::get_app_id(&self.config.cloud)?); - let cloud_config = &self.config.cloud; + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; + let cloud_config = self.get_cloud_config(); self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; let response = client @@ -289,16 +315,21 @@ impl DozerGrpcCloudClient for CloudClient { } fn monitor(&mut self, cloud: Cloud) -> Result<(), OrchestrationError> { - monitor_app(&cloud, &self.config.cloud, self.runtime.clone()) + let cloud_config = self.get_cloud_config(); + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; + monitor_app(&cloud, app_id, cloud_config, self.runtime.clone()) .map_err(crate::errors::OrchestrationError::CloudError) } fn trace_logs(&mut self, cloud: Cloud, logs: LogCommandArgs) -> Result<(), OrchestrationError> { - let app_id = cloud - .app_id - .clone() - .unwrap_or(CloudAppContext::get_app_id(&self.config.cloud)?); - let cloud_config = &self.config.cloud; + let cloud_config = self.get_cloud_config(); + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; @@ -355,7 +386,7 @@ impl DozerGrpcCloudClient for CloudClient { } fn login( - runtime: Arc, + &self, cloud: Cloud, organisation_slug: Option, profile: Option, @@ -377,7 +408,7 @@ impl DozerGrpcCloudClient for CloudClient { Some(name) => name, }; - runtime.block_on(async move { + self.runtime.block_on(async move { let login_svc = LoginSvc::new( organisation_slug, cloud @@ -396,42 +427,15 @@ impl DozerGrpcCloudClient for CloudClient { cloud: Cloud, command: SecretsCommand, ) -> Result<(), OrchestrationError> { - let app_id_result = cloud - .app_id - .clone() - .map_or(CloudAppContext::get_app_id(&self.config.cloud), Ok); - - let config = self.config.clone(); - let cloud_config = &self.config.cloud; + let cloud_config = self.get_cloud_config(); + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; - let app_id = match app_id_result { - Ok(id) => Ok(id), - Err(_e) if matches!(command, SecretsCommand::Create { .. }) => { - let config_content = - dozer_types::serde_yaml::to_string(&config).map_err(|e| { - CloudError::ConfigCombineError(ConfigCombineError::ParseConfig(e)) - })?; - - let response = client - .create_application(CreateAppRequest { - files: vec![File { - name: "dozer.yaml".to_string(), - content: config_content, - }], - }) - .await - .map_err(map_tonic_error)? - .into_inner(); - - CloudAppContext::save_app_id(response.app_id.clone())?; - Ok(response.app_id) - } - Err(e) => Err(e), - }?; - match command { SecretsCommand::Create { name, value } => { client @@ -504,12 +508,12 @@ impl CloudClient { cloud: Cloud, version: VersionCommand, ) -> Result<(), OrchestrationError> { - let app_id = cloud - .app_id - .clone() - .unwrap_or(CloudAppContext::get_app_id(&self.config.cloud)?); + let cloud_config = self.get_cloud_config(); + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; - let cloud_config = &self.config.cloud; self.runtime.block_on(async move { let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; @@ -548,13 +552,13 @@ impl CloudClient { cloud: Cloud, endpoint: Option, ) -> Result<(), OrchestrationError> { - let app_id = cloud - .app_id - .clone() - .unwrap_or(CloudAppContext::get_app_id(&self.config.cloud)?); - let cloud_config = &self.config.cloud; + let cloud_config = self.get_cloud_config(); + let app_id = self + .get_app_id() + .map(|a| a.0) + .ok_or_else(|| CloudContextError::AppIdNotFound)?; self.runtime.block_on(async move { - let mut client = get_grpc_cloud_client(&cloud, cloud_config).await?; + let mut client = get_grpc_cloud_client(&cloud, cloud_config.clone()).await?; let mut explorer_client = get_explorer_client(&cloud, cloud_config).await?; let response = client diff --git a/dozer-cli/src/cloud/deployer.rs b/dozer-cli/src/cloud/deployer.rs index f4b661dd18..f250950045 100644 --- a/dozer-cli/src/cloud/deployer.rs +++ b/dozer-cli/src/cloud/deployer.rs @@ -34,10 +34,11 @@ pub async fn deploy_app( let deployment_id = response.deployment_id; let url = response.deployment_url; info!("Deploying new application with App Id: {app_id}, Deployment Id: {deployment_id}"); - info!("Follow the deployment progress at {url}"); - + CloudAppContext::save_app_id(app_id.clone())?; if follow { print_progress(client, app_id, deployment_id).await?; + } else { + info!("Follow the deployment progress at {url}"); } Ok::<(), CloudError>(()) @@ -63,12 +64,11 @@ async fn print_progress( if response.status == DeploymentStatus::Success as i32 { info!("Deployment completed successfully"); info!("You can get API requests samples with `dozer cloud api-request-samples`"); - - CloudAppContext::save_app_id(app_id)?; - break; } else if response.status == DeploymentStatus::Failed as i32 { warn!("Deployment failed!"); + info!("Cleaning up..."); + CloudAppContext::delete_config_file()?; break; } else { let steps = response.steps.clone(); diff --git a/dozer-cli/src/cloud/mod.rs b/dozer-cli/src/cloud/mod.rs index 588ea092a2..e26a8901ad 100644 --- a/dozer-cli/src/cloud/mod.rs +++ b/dozer-cli/src/cloud/mod.rs @@ -12,8 +12,6 @@ pub mod monitor; pub mod progress_printer; mod token_layer; pub use client::CloudClient; -use tokio::runtime::Runtime; - pub trait DozerGrpcCloudClient { fn deploy( &mut self, @@ -21,13 +19,15 @@ pub trait DozerGrpcCloudClient { deploy: DeployCommandArgs, config_paths: Vec, ) -> Result<(), OrchestrationError>; + fn create(&mut self, cloud: Cloud, config_paths: Vec) + -> Result<(), OrchestrationError>; fn delete(&mut self, cloud: Cloud) -> Result<(), OrchestrationError>; fn list(&mut self, cloud: Cloud, list: ListCommandArgs) -> Result<(), OrchestrationError>; fn status(&mut self, cloud: Cloud) -> Result<(), OrchestrationError>; fn monitor(&mut self, cloud: Cloud) -> Result<(), OrchestrationError>; fn trace_logs(&mut self, cloud: Cloud, logs: LogCommandArgs) -> Result<(), OrchestrationError>; fn login( - runtime: std::sync::Arc, + &self, cloud: Cloud, organisation_slug: Option, profile: Option, diff --git a/dozer-cli/src/cloud/monitor.rs b/dozer-cli/src/cloud/monitor.rs index 385feb58f8..36c8be12af 100644 --- a/dozer-cli/src/cloud/monitor.rs +++ b/dozer-cli/src/cloud/monitor.rs @@ -1,6 +1,5 @@ use crate::cli::cloud::Cloud; use crate::cloud::client::get_grpc_cloud_client; -use crate::cloud::cloud_app_context::CloudAppContext; use crate::cloud::token_layer::TokenLayer; use crate::errors::CloudError; use dozer_types::grpc_types::cloud::dozer_cloud_client::DozerCloudClient; @@ -13,14 +12,10 @@ use tokio::runtime::Runtime; pub fn monitor_app( cloud: &Cloud, - cloud_config: &dozer_types::models::cloud::Cloud, + app_id: String, + cloud_config: Option, runtime: Arc, ) -> Result<(), CloudError> { - let app_id = cloud - .app_id - .clone() - .unwrap_or(CloudAppContext::get_app_id(cloud_config)?); - runtime.block_on(async move { let mut client: DozerCloudClient = get_grpc_cloud_client(cloud, cloud_config).await?; diff --git a/dozer-cli/src/errors.rs b/dozer-cli/src/errors.rs index ff97423846..17628e4151 100644 --- a/dozer-cli/src/errors.rs +++ b/dozer-cli/src/errors.rs @@ -283,4 +283,7 @@ pub enum CloudContextError { #[error("App id not found in configuration. You need to run \"deploy\" or \"set-app\" first")] AppIdNotFound, + + #[error("App id already exists. If you want to create a new app, please remove your cloud configuration")] + AppIdAlreadyExists(String), } diff --git a/dozer-cli/src/live/mod.rs b/dozer-cli/src/live/mod.rs index 9fe3b27873..43daff6ad4 100644 --- a/dozer-cli/src/live/mod.rs +++ b/dozer-cli/src/live/mod.rs @@ -1,7 +1,7 @@ mod downloader; mod errors; mod server; -mod state; +pub mod state; mod watcher; use self::state::LiveState; use crate::{cli::types::Live, live::server::LIVE_PORT}; diff --git a/dozer-cli/src/live/state.rs b/dozer-cli/src/live/state.rs index 3f9e710284..4d2ceb2089 100644 --- a/dozer-cli/src/live/state.rs +++ b/dozer-cli/src/live/state.rs @@ -57,6 +57,11 @@ pub struct LiveState { sender: RwLock>>, } +impl Default for LiveState { + fn default() -> Self { + Self::new() + } +} impl LiveState { pub fn new() -> Self { Self { @@ -311,7 +316,7 @@ fn get_contract(dozer_and_contract: &Option) -> Result<&Contra .ok_or(LiveError::NotInitialized) } -async fn create_contract(dozer: SimpleOrchestrator) -> Result { +pub async fn create_contract(dozer: SimpleOrchestrator) -> Result { let dag = create_dag(&dozer).await?; let version = dozer.config.version; let schemas = DagSchemas::new(dag)?; @@ -327,7 +332,7 @@ async fn create_contract(dozer: SimpleOrchestrator) -> Result Result { +pub async fn create_dag(dozer: &SimpleOrchestrator) -> Result { let endpoint_and_logs = dozer .config .endpoints diff --git a/dozer-cli/src/main.rs b/dozer-cli/src/main.rs index f28b8a0298..8afc1cc1ef 100644 --- a/dozer-cli/src/main.rs +++ b/dozer-cli/src/main.rs @@ -108,7 +108,7 @@ async fn check_update() { // We dont show error if error is connection error, because mostly it happens // when main thread is shutting down before request completes. if !e.is_connect() { - warn!("Unable to fetch the latest metadata"); + warn!("Unable to fetch the latest metadata"); } debug!("Updates check error: {}", e); @@ -131,71 +131,12 @@ fn run() -> Result<(), OrchestrationError> { set_panic_hook(); - // Run Cloud - #[cfg(feature = "cloud")] - if let Commands::Cloud(cloud) = &cli.cmd { - render_logo(); - let cloud = cloud.clone(); - let res = if let CloudCommands::Login { - organisation_slug, - profile_name, - client_id, - client_secret, - } = cloud.command.clone() - { - CloudClient::login( - runtime.clone(), - cloud, - organisation_slug, - profile_name, - client_id, - client_secret, - ) - } else { - let config = init_configuration(&cli, runtime.clone())?; - let mut cloud_client = CloudClient::new(config.clone(), runtime.clone()); - match cloud.command.clone() { - CloudCommands::Deploy(deploy) => { - cloud_client.deploy(cloud, deploy, cli.config_paths.clone()) - } - CloudCommands::Login { - organisation_slug: _, - profile_name: _, - client_id: _, - client_secret: _, - } => unreachable!("This is handled earlier"), - CloudCommands::Secrets(command) => { - cloud_client.execute_secrets_command(cloud, command) - } - CloudCommands::Delete => cloud_client.delete(cloud), - CloudCommands::Status => cloud_client.status(cloud), - CloudCommands::Monitor => cloud_client.monitor(cloud), - CloudCommands::Logs(logs) => cloud_client.trace_logs(cloud, logs), - CloudCommands::Version(version) => cloud_client.version(cloud, version), - CloudCommands::List(list) => cloud_client.list(cloud, list), - CloudCommands::SetApp { app_id } => { - CloudAppContext::save_app_id(app_id.clone())?; - info!("Using \"{app_id}\" app"); - Ok(()) - } - CloudCommands::ApiRequestSamples { endpoint } => { - cloud_client.print_api_request_samples(cloud, endpoint) - } - } - }; - - return match res { - Ok(_) => Ok(()), - Err(e) => { - println!("{}", e); - Err(e) - } - }; - } - - let config = init_configuration(&cli, runtime.clone())?; + let config_res = init_configuration(&cli, runtime.clone()); // Now we have access to telemetry configuration. Telemetry must be initialized in tokio runtime. - let app_id = config.cloud.app_id.as_deref().unwrap_or(&config.app_name); + let app_id = config_res + .as_ref() + .map(|c| c.cloud.app_id.as_deref().unwrap_or(&c.app_name)) + .ok(); // We always enable telemetry when running live. let telemetry_config = if matches!(cli.cmd, Commands::Live(_)) { @@ -204,10 +145,20 @@ fn run() -> Result<(), OrchestrationError> { metrics: Some(TelemetryMetricsConfig::Prometheus), } } else { - config.telemetry.clone() + config_res + .as_ref() + .map(|c| c.telemetry.clone()) + .unwrap_or_default() }; - let _telemetry = runtime.block_on(async { Telemetry::new(Some(app_id), &telemetry_config) }); + let _telemetry = runtime.block_on(async { Telemetry::new(app_id, &telemetry_config) }); + + // Run Cloud + #[cfg(feature = "cloud")] + if let Commands::Cloud(cloud) = &cli.cmd { + return run_cloud(cloud, runtime, &cli); + } + let config = config_res?; let mut dozer = init_dozer( runtime.clone(), @@ -279,6 +230,51 @@ fn run() -> Result<(), OrchestrationError> { }) } +#[cfg(feature = "cloud")] +fn run_cloud( + cloud: &dozer_cli::cli::cloud::Cloud, + runtime: Arc, + cli: &Cli, +) -> Result<(), OrchestrationError> { + render_logo(); + let cloud = cloud.clone(); + + let config = init_configuration(cli, runtime.clone()).ok(); + let mut cloud_client = CloudClient::new(config.clone(), runtime.clone()); + match cloud.command.clone() { + CloudCommands::Deploy(deploy) => { + cloud_client.deploy(cloud, deploy, cli.config_paths.clone()) + } + CloudCommands::Login { + organisation_slug, + profile_name, + client_id, + client_secret, + } => cloud_client.login( + cloud, + organisation_slug, + profile_name, + client_id, + client_secret, + ), + CloudCommands::Secrets(command) => cloud_client.execute_secrets_command(cloud, command), + CloudCommands::Delete => cloud_client.delete(cloud), + CloudCommands::Status => cloud_client.status(cloud), + CloudCommands::Monitor => cloud_client.monitor(cloud), + CloudCommands::Logs(logs) => cloud_client.trace_logs(cloud, logs), + CloudCommands::Version(version) => cloud_client.version(cloud, version), + CloudCommands::List(list) => cloud_client.list(cloud, list), + CloudCommands::SetApp { app_id } => { + CloudAppContext::save_app_id(app_id.clone())?; + info!("Using \"{app_id}\" app"); + Ok(()) + } + CloudCommands::ApiRequestSamples { endpoint } => { + cloud_client.print_api_request_samples(cloud, endpoint) + } + } +} + // Some commands dont need to initialize the orchestrator // This function is used to run those commands fn parse_and_generate() -> Result { @@ -321,10 +317,7 @@ fn init_configuration(cli: &Cli, runtime: Arc) -> Result { - error!("{}", e); - Err(e) - } + Err(e) => Err(e), } }, ) diff --git a/dozer-cli/src/simple/orchestrator.rs b/dozer-cli/src/simple/orchestrator.rs index 8b969a2bfb..3421662dd2 100644 --- a/dozer-cli/src/simple/orchestrator.rs +++ b/dozer-cli/src/simple/orchestrator.rs @@ -211,7 +211,7 @@ impl SimpleOrchestrator { } pub fn lockfile_path(&self) -> Utf8PathBuf { - self.base_directory.join(LOCK_FILE) + lockfile_path(self.base_directory.clone()) } pub fn run_apps( @@ -469,3 +469,7 @@ pub fn validate_sql(sql: String) -> Result<(), PipelineError> { }, ) } + +pub fn lockfile_path(base_directory: Utf8PathBuf) -> Utf8PathBuf { + base_directory.join(LOCK_FILE) +} diff --git a/dozer-types/protos/cloud.proto b/dozer-types/protos/cloud.proto index 3953523c4e..cd46eefef5 100644 --- a/dozer-types/protos/cloud.proto +++ b/dozer-types/protos/cloud.proto @@ -31,6 +31,7 @@ service DozerCloud { rpc delete_version(DeleteVersionRequest) returns (DeleteVersionResponse); rpc list_files(ListFilesRequest) returns (ListFilesResponse); rpc get_configuration(GetConfigurationRequest) returns (GetConfigurationResponse); + rpc get_all_schemas(GetAllSchemasRequest) returns (GetAllSchemasResponse); // returns a list of all the steps for a deployment rpc get_deployment_status(GetDeploymentStatusRequest) returns (GetDeploymentStatusResponse); @@ -121,6 +122,15 @@ message ListAppResponse { Pagination pagination = 2; } +message GetAllSchemasRequest { + string yaml = 1; +} + +message GetAllSchemasResponse { + map connections = 1; + dozer.types.SchemasResponse endpoints = 2; +} + message UpdateAppRequest { string app_id = 1; repeated File files = 2; @@ -272,13 +282,8 @@ message ListFilesRequest { string app_id = 1; } message ListFilesResponse { - repeated FileInfo files = 1; + repeated File files = 1; } -message FileInfo { - string id = 1; - File file = 2; -} - message LogMessageRequest { string app_id = 1; uint32 version = 2; diff --git a/dozer-types/protos/cloud_types.proto b/dozer-types/protos/cloud_types.proto index 435705d386..e0ead74cc6 100644 --- a/dozer-types/protos/cloud_types.proto +++ b/dozer-types/protos/cloud_types.proto @@ -1,15 +1,6 @@ syntax = "proto3"; package dozer.cloud; -message TableInfo { - string table_name = 1; - repeated ColumnInfo columns = 2; -} -message ColumnInfo { - string column_name = 1; - bool is_nullable = 2; -} - message File { string name = 1; string content = 2;