Skip to content

Commit

Permalink
shows better error msg when tembo context or credentials files are in…
Browse files Browse the repository at this point in the history
…valid (#586)
  • Loading branch information
shahadarsh committed Feb 27, 2024
1 parent a25364d commit 621ff52
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 108 deletions.
2 changes: 1 addition & 1 deletion tembo-cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tembo-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
workspace = { members = ["temboclient", "tembodataclient"] }
[package]
name = "tembo-cli"
version = "0.18.1"
version = "0.18.2"
edition = "2021"
authors = ["Tembo.io"]
description = "The CLI for Tembo"
Expand Down
67 changes: 49 additions & 18 deletions tembo-cli/src/cli/context.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::fs;

use anyhow::{anyhow, bail, Ok};
use anyhow::Error;
use anyhow::{anyhow, bail};
use serde::Deserialize;
use serde::Serialize;

use crate::tui;

// TODO: Move this to a template file
pub const CONTEXT_DEFAULT_TEXT: &str = "version = \"1.0\"
Expand Down Expand Up @@ -88,46 +91,74 @@ pub fn tembo_credentials_file_path() -> String {
tembo_home_dir() + "/credentials"
}

pub fn list_context() -> Result<Context, anyhow::Error> {
pub fn list_context() -> Result<Option<Context>, anyhow::Error> {
let filename = tembo_context_file_path();

let contents = fs::read_to_string(&filename)
.map_err(|err| anyhow!("Error reading file {filename}: {err}"))?;

let context: Context =
toml::from_str(&contents).map_err(|err| anyhow!("Error reading file {filename}: {err}"))?;
let maybe_context: Result<Context, toml::de::Error> = toml::from_str(&contents);

match maybe_context {
Ok(context) => Ok(Some(context)),
Err(err) => {
eprintln!("\nInvalid context file {filename}\n");

tui::error(&format!("Error: {}", err.message()));

eprintln!("\nExample context file: \n\n{}", CONTEXT_DEFAULT_TEXT);

Ok(context)
Err(Error::msg("Error listing tembo context!"))
}
}
}

pub fn get_current_context() -> Result<Environment, anyhow::Error> {
let context = list_context()?;
let maybe_context = list_context()?;

let profiles = list_credential_profiles()?;
if let Some(context) = maybe_context {
let maybe_profiles = list_credential_profiles()?;

for mut env in context.environment {
if let Some(_is_set) = env.set {
if let Some(profile) = &env.profile {
let credential = profiles.iter().rev().find(|c| &c.name == profile).unwrap();
if let Some(profiles) = maybe_profiles {
for mut env in context.environment {
if let Some(_is_set) = env.set {
if let Some(profile) = &env.profile {
let credential =
profiles.iter().rev().find(|c| &c.name == profile).unwrap();

env.selected_profile = Some(credential.to_owned());
}
env.selected_profile = Some(credential.to_owned());
}

return Ok(env);
return Ok(env);
}
}
}
}

bail!("Tembo context not set");
}

pub fn list_credential_profiles() -> Result<Vec<Profile>, anyhow::Error> {
pub fn list_credential_profiles() -> Result<Option<Vec<Profile>>, anyhow::Error> {
let filename = tembo_credentials_file_path();

let contents = fs::read_to_string(&filename)
.map_err(|err| anyhow!("Error reading file {filename}: {err}"))?;

let credential: Credential = toml::from_str(&contents)
.map_err(|err| anyhow!("Issue with the format of the TOML file {filename}: {err}"))?;
let maybe_credential: Result<Credential, toml::de::Error> = toml::from_str(&contents);

match maybe_credential {
Ok(credential) => Ok(Some(credential.profile)),
Err(err) => {
eprintln!("\nInvalid credentials file {filename}\n");

tui::error(&format!("Error: {}", err.message()));

Ok(credential.profile)
eprintln!(
"\nExample credentials file: \n\n{}",
CREDENTIALS_DEFAULT_TEXT
);

Err(Error::msg("Error listing tembo credentials profiles!"))
}
}
}
20 changes: 0 additions & 20 deletions tembo-cli/src/cli/extension.rs

This file was deleted.

1 change: 0 additions & 1 deletion tembo-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub mod context;
pub mod docker;
pub mod extension;
pub mod file_utils;
pub mod sqlx_utils;
pub mod tembo_config;
98 changes: 50 additions & 48 deletions tembo-cli/src/cmd/context/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,63 @@ use cli_table::{Cell, CellStruct, Style, Table};
use colorful::Colorful;

pub fn execute() -> Result<(), anyhow::Error> {
let context = list_context()?;
let maybe_context = list_context()?;

let mut rows: Vec<Vec<CellStruct>> = vec![];
let current_context_profile = context
.environment
.iter()
.find(|e| e.set.is_some())
.unwrap()
.name
.clone();
for e in context.environment {
let mut org_id = String::from(" ");
let mut profile = String::from(" ");
let mut set = false;
if let Some(env_org) = e.org_id {
org_id = env_org;
}
if let Some(context) = maybe_context {
let mut rows: Vec<Vec<CellStruct>> = vec![];
let current_context_profile = context
.environment
.iter()
.find(|e| e.set.is_some())
.unwrap()
.name
.clone();
for e in context.environment {
let mut org_id = String::from(" ");
let mut profile = String::from(" ");
let mut set = false;
if let Some(env_org) = e.org_id {
org_id = env_org;
}

if e.target == *"docker" {
profile = String::from("local")
} else if let Some(env_profile) = e.profile {
profile = env_profile;
}
if e.target == *"docker" {
profile = String::from("local")
} else if let Some(env_profile) = e.profile {
profile = env_profile;
}

if let Some(env_set) = e.set {
set = env_set;
}
if let Some(env_set) = e.set {
set = env_set;
}

rows.push(vec![
e.name.cell(),
e.target.cell(),
org_id.cell(),
profile.cell(),
set.cell(),
]);
}
rows.push(vec![
e.name.cell(),
e.target.cell(),
org_id.cell(),
profile.cell(),
set.cell(),
]);
}

let table = rows
.table()
.title(vec![
"Name".color(sql_u()).cell().bold(true),
"Target".color(sql_u()).cell().bold(true),
"Org ID".color(sql_u()).cell().bold(true),
"Profile".color(sql_u()).cell().bold(true),
"Set".color(sql_u()).cell().bold(true),
])
.bold(true);
let table = rows
.table()
.title(vec![
"Name".color(sql_u()).cell().bold(true),
"Target".color(sql_u()).cell().bold(true),
"Org ID".color(sql_u()).cell().bold(true),
"Profile".color(sql_u()).cell().bold(true),
"Set".color(sql_u()).cell().bold(true),
])
.bold(true);

let table_display = table
.display()
.expect("Error: could not parse `tembo context list` table contents!");
let table_display = table
.display()
.expect("Error: could not parse `tembo context list` table contents!");

label_with_value("Your current Tembo context:", &current_context_profile);
println!("{}", indent(1));
println!("{}", table_display);
label_with_value("Your current Tembo context:", &current_context_profile);
println!("{}", indent(1));
println!("{}", table_display);
}

Ok(())
}
27 changes: 9 additions & 18 deletions tembo-cli/src/cmd/top.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
use crate::cli::context::{get_current_context, Environment, Profile, Target};
use crate::cli::context::{get_current_context, Environment};
use crate::cli::tembo_config::InstanceSettings;
use crate::cmd::apply::get_instance_settings;
use crate::Args;
use anyhow::anyhow;
use anyhow::{Context, Result};
use crossterm::{
cursor::{MoveTo, MoveUp},
execute,
terminal::{Clear, ClearType},
};
use hyper::header::ACCEPT;
use reqwest::header::HeaderMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use std::io::{stdout, Write};
use temboclient::models::{instance, instance_event};
use temboclient::{
apis::{
configuration::Configuration,
instance_api::{create_instance, get_all, get_instance, put_instance},
},
models::connection_info,
};
use temboclient::apis::configuration::Configuration;
use temboclient::apis::instance_api::get_all;
use temboclient::apis::instance_api::get_instance;
use tokio::runtime::Runtime;
use tokio::time::{interval, Duration};
use tokio::time::Duration;

#[derive(Args)]
pub struct TopCommand {}
Expand All @@ -39,7 +30,7 @@ pub struct MetricsResponse {

#[derive(Serialize, Deserialize, Debug)]
pub struct MetricsData {
pub resultType: String,
pub result_type: String,
pub result: Vec<MetricResult>,
}

Expand Down Expand Up @@ -101,8 +92,8 @@ async fn fetch_metrics_loop(
loop {
execute!(stdout, Clear(ClearType::All))?;

for (key, value) in &instance_settings {
let org_name = get_instance_org_name(&config, &env, &value.instance_name).await?;
for value in instance_settings.values() {
let org_name = get_instance_org_name(config, &env, &value.instance_name).await?;
let namespace = format!("org-{}-inst-{}", org_name, &value.instance_name);
let namespace_encoded = urlencoding::encode(&namespace);

Expand Down Expand Up @@ -249,7 +240,7 @@ async fn get_instance_org_name(
instance_name
))
}
Err(e) => return Err(e.into()),
Err(e) => return Err(e),
};
let org_id = env
.org_id
Expand Down
6 changes: 5 additions & 1 deletion tembo-cli/src/cmd/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use crate::cli::file_utils::FileUtils;
use crate::cli::tembo_config::InstanceSettings;
use crate::tui::{error, info, white_confirmation};
use anyhow::Error;
use anyhow::Ok;
use clap::Args;
use std::{collections::HashMap, fs, path::Path, str::FromStr};
use tembo::cli::context::{list_context, list_credential_profiles};

/// Validates the tembo.toml file, context file, etc.
#[derive(Args)]
Expand All @@ -20,6 +20,8 @@ pub fn execute(verbose: bool) -> Result<(), anyhow::Error> {
tembo_context_file_path()
));
has_error = true
} else {
list_context()?;
}
if verbose {
info("Context file exists");
Expand All @@ -31,6 +33,8 @@ pub fn execute(verbose: bool) -> Result<(), anyhow::Error> {
tembo_credentials_file_path()
);
has_error = true
} else {
list_credential_profiles()?;
}
if verbose {
info("Credentials file exists");
Expand Down

0 comments on commit 621ff52

Please sign in to comment.