generated from pure_sagacity/rust-starter
fixed tests, and added the deletion and overwriting confirmation
This commit is contained in:
+53
-28
@@ -125,9 +125,18 @@ pub enum Commands {
|
|||||||
vars: Vec<String>,
|
vars: Vec<String>,
|
||||||
},
|
},
|
||||||
Delete {
|
Delete {
|
||||||
|
#[arg(short = 'e', long = "environment")]
|
||||||
|
environment: Option<String>,
|
||||||
|
|
||||||
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
|
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
|
||||||
keys: Vec<String>,
|
keys: Vec<String>,
|
||||||
},
|
},
|
||||||
|
Show {
|
||||||
|
#[arg(short = 'e', long = "environment")]
|
||||||
|
environment: Option<String>,
|
||||||
|
|
||||||
|
key: String,
|
||||||
|
},
|
||||||
Setup {},
|
Setup {},
|
||||||
List {},
|
List {},
|
||||||
Project {
|
Project {
|
||||||
@@ -212,6 +221,10 @@ pub mod interactions {
|
|||||||
|
|
||||||
type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
|
fn db_url() -> String {
|
||||||
|
std::env::var("DATABASE_URL").unwrap_or_else(|_| DB_URL.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
fn construct_error(message: &str) -> Result<()> {
|
fn construct_error(message: &str) -> Result<()> {
|
||||||
Err(Box::new(std::io::Error::new(
|
Err(Box::new(std::io::Error::new(
|
||||||
std::io::ErrorKind::AlreadyExists,
|
std::io::ErrorKind::AlreadyExists,
|
||||||
@@ -221,7 +234,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn project_exists(proj_name: &str) -> Result<bool> {
|
pub fn project_exists(proj_name: &str) -> Result<bool> {
|
||||||
use super::db::schema::projects::dsl::{name, projects};
|
use super::db::schema::projects::dsl::{name, projects};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let existing_project = projects
|
let existing_project = projects
|
||||||
.filter(name.eq(proj_name))
|
.filter(name.eq(proj_name))
|
||||||
@@ -234,7 +247,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn create_project(proj_name: &str) -> Result<()> {
|
pub fn create_project(proj_name: &str) -> Result<()> {
|
||||||
use super::db::schema::projects::dsl::{created_at, id, name, projects};
|
use super::db::schema::projects::dsl::{created_at, id, name, projects};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
if project_exists(proj_name)? {
|
if project_exists(proj_name)? {
|
||||||
return construct_error("Project already exists");
|
return construct_error("Project already exists");
|
||||||
@@ -260,7 +273,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn delete_project(proj_name: &str) -> Result<()> {
|
pub fn delete_project(proj_name: &str) -> Result<()> {
|
||||||
use super::db::schema::projects::dsl::{name, projects};
|
use super::db::schema::projects::dsl::{name, projects};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
if !project_exists(proj_name)? {
|
if !project_exists(proj_name)? {
|
||||||
return construct_error("Project does not exist");
|
return construct_error("Project does not exist");
|
||||||
@@ -273,7 +286,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn get_projects() -> Result<Vec<Project>> {
|
pub fn get_projects() -> Result<Vec<Project>> {
|
||||||
use super::db::schema::projects::dsl::projects;
|
use super::db::schema::projects::dsl::projects;
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let results = projects
|
let results = projects
|
||||||
.select(Project::as_select())
|
.select(Project::as_select())
|
||||||
@@ -288,7 +301,7 @@ pub mod interactions {
|
|||||||
environment: Environment,
|
environment: Environment,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
use super::db::schema::secrets::dsl::{config, id, name, project_id, secrets};
|
use super::db::schema::secrets::dsl::{config, id, name, project_id, secrets};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let existing_secret = secrets
|
let existing_secret = secrets
|
||||||
.filter(project_id.eq(proj_id))
|
.filter(project_id.eq(proj_id))
|
||||||
@@ -303,7 +316,7 @@ pub mod interactions {
|
|||||||
|
|
||||||
pub fn get_project_id(proj_name: &str) -> Result<String> {
|
pub fn get_project_id(proj_name: &str) -> Result<String> {
|
||||||
use super::db::schema::projects::dsl::{id, name, projects};
|
use super::db::schema::projects::dsl::{id, name, projects};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let project_id = projects
|
let project_id = projects
|
||||||
.filter(name.eq(proj_name))
|
.filter(name.eq(proj_name))
|
||||||
@@ -330,26 +343,30 @@ pub mod interactions {
|
|||||||
use super::db::schema::secrets::dsl::{
|
use super::db::schema::secrets::dsl::{
|
||||||
config, created_at, id, name, nonce, project_id, secret, secrets,
|
config, created_at, id, name, nonce, project_id, secret, secrets,
|
||||||
};
|
};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
if secret_exists(proj_id, secret_name, conf)? {
|
if secret_exists(proj_id, secret_name, conf)? {
|
||||||
return Err(Box::new(std::io::Error::new(
|
update(
|
||||||
std::io::ErrorKind::AlreadyExists,
|
secrets
|
||||||
"Secret already exists",
|
.filter(project_id.eq(proj_id))
|
||||||
)));
|
.filter(name.eq(secret_name))
|
||||||
}
|
.filter(config.eq(conf)),
|
||||||
|
)
|
||||||
insert_into(secrets)
|
.set((secret.eq(secret_value), nonce.eq(non.to_vec())))
|
||||||
.values((
|
|
||||||
id.eq(Uuid::new_v4().to_string()),
|
|
||||||
name.eq(secret_name),
|
|
||||||
secret.eq(secret_value),
|
|
||||||
project_id.eq(proj_id),
|
|
||||||
config.eq(conf),
|
|
||||||
nonce.eq(non.to_vec()),
|
|
||||||
created_at.eq(chrono::Utc::now().naive_utc()),
|
|
||||||
))
|
|
||||||
.execute(&mut conn)?;
|
.execute(&mut conn)?;
|
||||||
|
} else {
|
||||||
|
insert_into(secrets)
|
||||||
|
.values((
|
||||||
|
id.eq(Uuid::new_v4().to_string()),
|
||||||
|
name.eq(secret_name),
|
||||||
|
secret.eq(secret_value),
|
||||||
|
project_id.eq(proj_id),
|
||||||
|
config.eq(conf),
|
||||||
|
nonce.eq(non.to_vec()),
|
||||||
|
created_at.eq(chrono::Utc::now().naive_utc()),
|
||||||
|
))
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -359,7 +376,7 @@ pub mod interactions {
|
|||||||
environment: Environment,
|
environment: Environment,
|
||||||
) -> Result<Vec<(String, Vec<u8>, Vec<u8>)>> {
|
) -> Result<Vec<(String, Vec<u8>, Vec<u8>)>> {
|
||||||
use super::db::schema::secrets::dsl::{config, name, nonce, project_id, secret, secrets};
|
use super::db::schema::secrets::dsl::{config, name, nonce, project_id, secret, secrets};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let results = secrets
|
let results = secrets
|
||||||
.filter(project_id.eq(proj_id))
|
.filter(project_id.eq(proj_id))
|
||||||
@@ -370,12 +387,14 @@ pub mod interactions {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_secret(secret_name: &str) -> Result<()> {
|
pub fn delete_secret(proj_id: &str, secret_name: &str, environment: Environment) -> Result<()> {
|
||||||
use super::db::schema::secrets::dsl::{id, name, secrets};
|
use super::db::schema::secrets::dsl::{config, id, name, project_id, secrets};
|
||||||
let mut conn = establish_connection(DB_URL.to_string());
|
let mut conn = establish_connection(db_url());
|
||||||
|
|
||||||
let existing_secret = secrets
|
let existing_secret = secrets
|
||||||
|
.filter(project_id.eq(proj_id))
|
||||||
.filter(name.eq(secret_name))
|
.filter(name.eq(secret_name))
|
||||||
|
.filter(config.eq(environment))
|
||||||
.select(id)
|
.select(id)
|
||||||
.first::<String>(&mut conn)
|
.first::<String>(&mut conn)
|
||||||
.optional()?;
|
.optional()?;
|
||||||
@@ -387,7 +406,13 @@ pub mod interactions {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::delete(secrets.filter(name.eq(secret_name))).execute(&mut conn)?;
|
diesel::delete(
|
||||||
|
secrets
|
||||||
|
.filter(project_id.eq(proj_id))
|
||||||
|
.filter(name.eq(secret_name))
|
||||||
|
.filter(config.eq(environment)),
|
||||||
|
)
|
||||||
|
.execute(&mut conn)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+167
-6
@@ -12,6 +12,7 @@ use cli::interactions::delete_secret;
|
|||||||
use cli::interactions::get_project_id;
|
use cli::interactions::get_project_id;
|
||||||
use cli::interactions::get_project_secrets;
|
use cli::interactions::get_project_secrets;
|
||||||
use cli::interactions::get_projects;
|
use cli::interactions::get_projects;
|
||||||
|
use cli::interactions::secret_exists;
|
||||||
use cli::interactions::set_secret;
|
use cli::interactions::set_secret;
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use crypto::encrypt;
|
use crypto::encrypt;
|
||||||
@@ -55,6 +56,80 @@ fn main() {
|
|||||||
print_error("Missing .harbor.toml. Run `harbor config create` first.");
|
print_error("Missing .harbor.toml. Run `harbor config create` first.");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
Commands::Show { environment, key } => {
|
||||||
|
let config = require_config(&root);
|
||||||
|
let environment: Environment = match environment {
|
||||||
|
Some(env) => match env.parse::<Environment>() {
|
||||||
|
Ok(parsed) => parsed,
|
||||||
|
Err(_) => {
|
||||||
|
print_error(format!("Invalid environment '{}'.", env));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => config.default_env.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let project = match get_project_id(&config.name) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!(
|
||||||
|
"Unable to get project ID for '{}': {}",
|
||||||
|
config.name, e
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let secrets = match get_project_secrets(&project, environment) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Error getting secrets: {}", e));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let secret = secrets.into_iter().find(|(name, _, _)| name == &key);
|
||||||
|
|
||||||
|
match secret {
|
||||||
|
Some((_, ciphertext, nonce)) => {
|
||||||
|
let key = match gen_or_get_key() {
|
||||||
|
Ok(k) => k,
|
||||||
|
Err(_) => {
|
||||||
|
print_error("Error generating or getting key");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let nonce = crypto::Nonce::from_slice(&nonce);
|
||||||
|
let decrypted = match crypto::decrypt(&key, ciphertext, nonce) {
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Error decrypting secret: {}", e));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let decrypted_str = match String::from_utf8(decrypted) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!(
|
||||||
|
"Error converting decrypted secret to string: {}",
|
||||||
|
e
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("{}", decrypted_str);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
print_error(format!(
|
||||||
|
"Secret with key '{}' not found in project '{}'.",
|
||||||
|
key, config.name
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Commands::Set { environment, vars } => {
|
Commands::Set { environment, vars } => {
|
||||||
let config = require_config(&root);
|
let config = require_config(&root);
|
||||||
let environment: Environment = match environment {
|
let environment: Environment = match environment {
|
||||||
@@ -93,6 +168,47 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for pair in pairs {
|
for pair in pairs {
|
||||||
|
let existed = match secret_exists(&project, &pair.0, environment) {
|
||||||
|
Ok(exists) => exists,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!(
|
||||||
|
"Error checking existing secret for key '{}': {}",
|
||||||
|
pair.0, e
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if existed {
|
||||||
|
let confirmation = match get_input(
|
||||||
|
format!(
|
||||||
|
"Secret '{}' already exists. Overwrite? (y/N)",
|
||||||
|
pair.0
|
||||||
|
)
|
||||||
|
.yellow(),
|
||||||
|
':',
|
||||||
|
false,
|
||||||
|
) {
|
||||||
|
Ok(input) => input,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!("Error getting confirmation: {}", e));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if confirmation.to_lowercase() != "y" {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
format!(
|
||||||
|
"Skipped secret '{}' in {}.",
|
||||||
|
pair.0,
|
||||||
|
environment.as_str()
|
||||||
|
)
|
||||||
|
.dimmed()
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let key = match gen_or_get_key() {
|
let key = match gen_or_get_key() {
|
||||||
Ok(k) => k,
|
Ok(k) => k,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@@ -111,7 +227,20 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
match set_secret(&project, &pair.0, encrypted, environment, nonce) {
|
match set_secret(&project, &pair.0, encrypted, environment, nonce) {
|
||||||
Ok(()) => {}
|
Ok(()) => {
|
||||||
|
let verb = if existed { "Updated" } else { "Set" };
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
format!(
|
||||||
|
"{} secret '{}' in {}.",
|
||||||
|
verb,
|
||||||
|
pair.0,
|
||||||
|
environment.as_str()
|
||||||
|
)
|
||||||
|
.bright_green()
|
||||||
|
.bold()
|
||||||
|
);
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
print_error(format!(
|
print_error(format!(
|
||||||
"Error setting secret for key '{}': {}",
|
"Error setting secret for key '{}': {}",
|
||||||
@@ -122,7 +251,28 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Commands::Delete { keys } => {
|
Commands::Delete { environment, keys } => {
|
||||||
|
let config = require_config(&root);
|
||||||
|
let environment: Environment = match environment {
|
||||||
|
Some(env) => match env.parse::<Environment>() {
|
||||||
|
Ok(parsed) => parsed,
|
||||||
|
Err(_) => {
|
||||||
|
print_error(format!("Invalid environment '{}'.", env));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => config.default_env.into(),
|
||||||
|
};
|
||||||
|
let proj_id = match get_project_id(&config.name) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => {
|
||||||
|
print_error(format!(
|
||||||
|
"Unable to get project ID for '{}': {}",
|
||||||
|
config.name, e
|
||||||
|
));
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
let mut cleaned = Vec::new();
|
let mut cleaned = Vec::new();
|
||||||
|
|
||||||
for key in keys {
|
for key in keys {
|
||||||
@@ -141,7 +291,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for key in cleaned {
|
for key in cleaned {
|
||||||
match delete_secret(&key) {
|
match delete_secret(&proj_id, &key, environment) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
println!("Deleted secret for key '{}'", key);
|
println!("Deleted secret for key '{}'", key);
|
||||||
}
|
}
|
||||||
@@ -300,7 +450,9 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match cli::interactions::create_project(&project_name) {
|
match cli::interactions::create_project(&project_name) {
|
||||||
Ok(()) => println!("{}", "Project created successfully.".cyan()),
|
Ok(()) => {
|
||||||
|
println!("{}", "Project created successfully.".bright_green().bold())
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
print_error(format!("Error creating project: {}", e));
|
print_error(format!("Error creating project: {}", e));
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
@@ -342,7 +494,10 @@ fn main() {
|
|||||||
if confirmation.to_lowercase() == "y" {
|
if confirmation.to_lowercase() == "y" {
|
||||||
match cli::interactions::delete_project(&name) {
|
match cli::interactions::delete_project(&name) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
println!("{}", "Project deleted successfully.".cyan())
|
println!(
|
||||||
|
"{}",
|
||||||
|
"Project deleted successfully.".bright_green().bold()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
print_error(format!("Error deleting project: {}", e));
|
print_error(format!("Error deleting project: {}", e));
|
||||||
@@ -530,7 +685,12 @@ config = "dev""#,
|
|||||||
let config_path = root.join(".harbor.toml");
|
let config_path = root.join(".harbor.toml");
|
||||||
match std::fs::write(&config_path, new_config) {
|
match std::fs::write(&config_path, new_config) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Created .harbor.toml for project '{}'.", project);
|
println!(
|
||||||
|
"{}",
|
||||||
|
format!("Created .harbor.toml for project '{}'.", project)
|
||||||
|
.bright_green()
|
||||||
|
.bold()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
print_error(format!(
|
print_error(format!(
|
||||||
@@ -571,6 +731,7 @@ fn requires_config(command: &cli::Commands) -> bool {
|
|||||||
matches!(
|
matches!(
|
||||||
command,
|
command,
|
||||||
cli::Commands::Inject { .. }
|
cli::Commands::Inject { .. }
|
||||||
|
| cli::Commands::Show { .. }
|
||||||
| cli::Commands::Set { .. }
|
| cli::Commands::Set { .. }
|
||||||
| cli::Commands::Delete { .. }
|
| cli::Commands::Delete { .. }
|
||||||
| cli::Commands::Shell { .. }
|
| cli::Commands::Shell { .. }
|
||||||
|
|||||||
@@ -1,15 +1,8 @@
|
|||||||
use cli::Environment;
|
use cli::Environment;
|
||||||
use cli::config::Config;
|
use cli::config::Config;
|
||||||
use cli::interactions::{
|
use cli::interactions::{
|
||||||
create_project,
|
create_project, delete_project, delete_secret, get_project_id, get_project_secrets,
|
||||||
delete_project,
|
get_projects, project_exists, secret_exists, set_secret,
|
||||||
delete_secret,
|
|
||||||
get_project_id,
|
|
||||||
get_project_secrets,
|
|
||||||
get_projects,
|
|
||||||
project_exists,
|
|
||||||
secret_exists,
|
|
||||||
set_secret,
|
|
||||||
};
|
};
|
||||||
use cli::{format_doppler_set_command, parse_secret_pairs};
|
use cli::{format_doppler_set_command, parse_secret_pairs};
|
||||||
use diesel::connection::SimpleConnection;
|
use diesel::connection::SimpleConnection;
|
||||||
@@ -70,7 +63,10 @@ fn environment_parsing_and_display() {
|
|||||||
assert_eq!(format!("{}", Environment::Prod), "prod");
|
assert_eq!(format!("{}", Environment::Prod), "prod");
|
||||||
|
|
||||||
let err = "unknown".parse::<Environment>().unwrap_err();
|
let err = "unknown".parse::<Environment>().unwrap_err();
|
||||||
assert_eq!(err.to_string(), "Environment must be one of: dev, prod, staging");
|
assert_eq!(
|
||||||
|
err.to_string(),
|
||||||
|
"Environment must be one of: dev, prod, staging"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -108,10 +104,7 @@ fn format_doppler_set_command_outputs_expected_format() {
|
|||||||
("B".to_string(), "2".to_string()),
|
("B".to_string(), "2".to_string()),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(many, "doppler secrets set \\\n A=\"1\" \\\n B=\"2\"");
|
||||||
many,
|
|
||||||
"doppler secrets set \\\n A=\"1\" \\\n B=\"2\""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -158,7 +151,7 @@ fn project_and_secret_lifecycle() {
|
|||||||
assert_eq!(projects.len(), 1);
|
assert_eq!(projects.len(), 1);
|
||||||
assert_eq!(projects[0].name, "alpha");
|
assert_eq!(projects[0].name, "alpha");
|
||||||
|
|
||||||
assert!(!secret_exists().expect("secret exists"));
|
assert!(!secret_exists(&project_id, "API_KEY", Environment::Dev).expect("secret exists"));
|
||||||
|
|
||||||
let nonce = crypto::helper::gen_nonce();
|
let nonce = crypto::helper::gen_nonce();
|
||||||
set_secret(
|
set_secret(
|
||||||
@@ -170,7 +163,7 @@ fn project_and_secret_lifecycle() {
|
|||||||
)
|
)
|
||||||
.expect("set secret");
|
.expect("set secret");
|
||||||
|
|
||||||
assert!(secret_exists().expect("secret exists"));
|
assert!(secret_exists(&project_id, "API_KEY", Environment::Dev).expect("secret exists"));
|
||||||
|
|
||||||
let secrets = get_project_secrets(&project_id, Environment::Dev).expect("get secrets");
|
let secrets = get_project_secrets(&project_id, Environment::Dev).expect("get secrets");
|
||||||
assert_eq!(secrets.len(), 1);
|
assert_eq!(secrets.len(), 1);
|
||||||
@@ -191,8 +184,8 @@ fn project_and_secret_lifecycle() {
|
|||||||
assert_eq!(updated.len(), 1);
|
assert_eq!(updated.len(), 1);
|
||||||
assert_eq!(updated[0].1, b"second".to_vec());
|
assert_eq!(updated[0].1, b"second".to_vec());
|
||||||
|
|
||||||
delete_secret("API_KEY").expect("delete secret");
|
delete_secret(&project_id, "API_KEY", Environment::Dev).expect("delete secret");
|
||||||
assert!(!secret_exists().expect("secret exists"));
|
assert!(!secret_exists(&project_id, "API_KEY", Environment::Dev).expect("secret exists"));
|
||||||
|
|
||||||
delete_project("alpha").expect("delete project");
|
delete_project("alpha").expect("delete project");
|
||||||
assert!(!project_exists("alpha").expect("project exists"));
|
assert!(!project_exists("alpha").expect("project exists"));
|
||||||
@@ -211,7 +204,8 @@ fn errors_for_missing_project_or_secret() {
|
|||||||
let err = get_project_id("missing").unwrap_err();
|
let err = get_project_id("missing").unwrap_err();
|
||||||
assert_eq!(err.to_string(), "Project not found");
|
assert_eq!(err.to_string(), "Project not found");
|
||||||
|
|
||||||
let err = delete_secret("missing").unwrap_err();
|
let missing_project_id = Uuid::new_v4().to_string();
|
||||||
|
let err = delete_secret(&missing_project_id, "missing", Environment::Dev).unwrap_err();
|
||||||
assert_eq!(err.to_string(), "Secret does not exist");
|
assert_eq!(err.to_string(), "Secret does not exist");
|
||||||
|
|
||||||
cleanup_test_db(db_path);
|
cleanup_test_db(db_path);
|
||||||
|
|||||||
Reference in New Issue
Block a user