Skip to content

Commit a098111

Browse files
committed
fix: standardize Cloud API env vars and support environment-only auth testing
- Standardized environment variable names to use REDIS_CLOUD_API_SECRET (not REDIS_CLOUD_API_SECRET_KEY) across all modules for consistency - Updated auth.rs, config.rs to use consistent env var names - Enhanced auth test command to support testing credentials from environment variables even when no profiles are configured - Auto-detects deployment type from environment variables when no profile is available Fixes authentication testing with environment variables only.
1 parent 353dd84 commit a098111

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

crates/redisctl/src/commands/auth.rs

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,32 +40,44 @@ async fn test_auth(
4040
config: &Config,
4141
output: OutputFormatter,
4242
) -> Result<()> {
43-
// Get the profile to test
44-
let (profile_name, profile) = if let Some(name) = profile_name {
43+
// Get the profile to test, or use environment variables if no profile is configured
44+
let (profile_name, profile_opt, deployment_type) = if let Some(name) = profile_name {
4545
let p = config
4646
.profiles
4747
.get(&name)
4848
.ok_or_else(|| anyhow::anyhow!("Profile '{}' not found", name))?;
49-
(name, p)
49+
let dt = deployment_override.unwrap_or(p.deployment_type);
50+
(name, Some(p), dt)
5051
} else {
5152
// Find active profile with its name
5253
let env_profile = std::env::var("REDISCTL_PROFILE").ok();
53-
let name = env_profile
54-
.as_deref()
55-
.or(config.default_profile.as_deref())
56-
.ok_or_else(|| {
57-
anyhow::anyhow!("No profile configured. Run 'redisctl auth setup' to get started.")
58-
})?;
59-
60-
let p = config
61-
.profiles
62-
.get(name)
63-
.ok_or_else(|| anyhow::anyhow!("Profile '{}' not found", name))?;
64-
(name.to_string(), p)
54+
if let Some(name) = env_profile.as_deref().or(config.default_profile.as_deref()) {
55+
let p = config
56+
.profiles
57+
.get(name)
58+
.ok_or_else(|| anyhow::anyhow!("Profile '{}' not found", name))?;
59+
let dt = deployment_override.unwrap_or(p.deployment_type);
60+
(name.to_string(), Some(p), dt)
61+
} else {
62+
// No profile configured, try to determine deployment type from environment or flag
63+
let deployment_type = if let Some(dt) = deployment_override {
64+
dt
65+
} else {
66+
// Try to detect deployment type from environment variables
67+
if std::env::var("REDIS_CLOUD_API_KEY").is_ok() {
68+
DeploymentType::Cloud
69+
} else if std::env::var("REDIS_ENTERPRISE_URL").is_ok() {
70+
DeploymentType::Enterprise
71+
} else {
72+
anyhow::bail!(
73+
"No profile configured and no deployment type specified. Use --deployment flag or run 'redisctl auth setup' to create a profile."
74+
)
75+
}
76+
};
77+
("environment".to_string(), None, deployment_type)
78+
}
6579
};
6680

67-
let deployment_type = deployment_override.unwrap_or(profile.deployment_type);
68-
6981
// Build result object to track all tests
7082
let mut result = json!({
7183
"profile": profile_name,
@@ -74,28 +86,29 @@ async fn test_auth(
7486
});
7587

7688
match deployment_type {
77-
DeploymentType::Cloud => test_cloud_auth(profile, &mut result).await?,
78-
DeploymentType::Enterprise => test_enterprise_auth(profile, &mut result).await?,
89+
DeploymentType::Cloud => test_cloud_auth(profile_opt, &mut result).await?,
90+
DeploymentType::Enterprise => test_enterprise_auth(profile_opt, &mut result).await?,
7991
}
8092

8193
output.format(&result)?;
8294
Ok(())
8395
}
8496

8597
/// Test Redis Cloud authentication
86-
async fn test_cloud_auth(profile: &Profile, result: &mut serde_json::Value) -> Result<()> {
98+
async fn test_cloud_auth(profile: Option<&Profile>, result: &mut serde_json::Value) -> Result<()> {
8799
let tests = result["tests"].as_object_mut().unwrap();
88100

89101
// Check for API credentials from profile or environment
90102
let (api_key, api_secret, _api_url) =
91-
if let Some((key, secret, url)) = profile.cloud_credentials() {
103+
if let Some(p) = profile.and_then(|p| p.cloud_credentials()) {
92104
tests.insert("credentials_present".to_string(), json!(true));
93-
(key.to_string(), secret.to_string(), url.to_string())
105+
tests.insert("source".to_string(), json!("profile"));
106+
(p.0.to_string(), p.1.to_string(), p.2.to_string())
94107
} else {
95108
// Try environment variables
96109
match (
97110
std::env::var("REDIS_CLOUD_API_KEY"),
98-
std::env::var("REDIS_CLOUD_API_SECRET_KEY"),
111+
std::env::var("REDIS_CLOUD_API_SECRET"),
99112
) {
100113
(Ok(key), Ok(secret)) => {
101114
tests.insert("credentials_present".to_string(), json!(true));
@@ -159,18 +172,22 @@ async fn test_cloud_auth(profile: &Profile, result: &mut serde_json::Value) -> R
159172
}
160173

161174
/// Test Redis Enterprise authentication
162-
async fn test_enterprise_auth(profile: &Profile, result: &mut serde_json::Value) -> Result<()> {
175+
async fn test_enterprise_auth(
176+
profile: Option<&Profile>,
177+
result: &mut serde_json::Value,
178+
) -> Result<()> {
163179
let tests = result["tests"].as_object_mut().unwrap();
164180

165181
// Check for credentials from profile or environment
166182
let (url, username, password, insecure) =
167-
if let Some((u, user, pass, ins)) = profile.enterprise_credentials() {
183+
if let Some(p) = profile.and_then(|p| p.enterprise_credentials()) {
168184
tests.insert("credentials_present".to_string(), json!(true));
185+
tests.insert("source".to_string(), json!("profile"));
169186
(
170-
u.to_string(),
171-
user.to_string(),
172-
pass.map(|p| p.to_string()),
173-
ins,
187+
p.0.to_string(),
188+
p.1.to_string(),
189+
p.2.map(|p| p.to_string()),
190+
p.3,
174191
)
175192
} else {
176193
// Try environment variables
@@ -364,11 +381,13 @@ async fn setup_wizard(config: &Config) -> Result<()> {
364381

365382
let success = match deployment_type {
366383
DeploymentType::Cloud => {
367-
test_cloud_auth(&profile, &mut test_result).await.is_ok()
384+
test_cloud_auth(Some(&profile), &mut test_result)
385+
.await
386+
.is_ok()
368387
&& test_result["tests"]["authentication"] == json!(true)
369388
}
370389
DeploymentType::Enterprise => {
371-
test_enterprise_auth(&profile, &mut test_result)
390+
test_enterprise_auth(Some(&profile), &mut test_result)
372391
.await
373392
.is_ok()
374393
&& test_result["tests"]["authentication"] == json!(true)

crates/redisctl/src/commands/config.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ fn show_config(config: &Config, show_secrets: bool, output: OutputFormatter) ->
113113
},
114114
);
115115
}
116-
if std::env::var("REDIS_CLOUD_API_SECRET_KEY").is_ok() {
116+
if std::env::var("REDIS_CLOUD_API_SECRET").is_ok() {
117117
env_vars.insert(
118-
"REDIS_CLOUD_API_SECRET_KEY",
118+
"REDIS_CLOUD_API_SECRET",
119119
if show_secrets {
120-
std::env::var("REDIS_CLOUD_API_SECRET_KEY").unwrap()
120+
std::env::var("REDIS_CLOUD_API_SECRET").unwrap()
121121
} else {
122122
"***".to_string()
123123
},
@@ -236,9 +236,9 @@ fn validate_profile(name: &str, profile: &crate::config::Profile) -> serde_json:
236236
}
237237

238238
// Check for API secret
239-
if api_secret.is_empty() && std::env::var("REDIS_CLOUD_API_SECRET_KEY").is_err() {
239+
if api_secret.is_empty() && std::env::var("REDIS_CLOUD_API_SECRET").is_err() {
240240
issues.push(
241-
"Missing API secret key (set in profile or REDIS_CLOUD_API_SECRET_KEY env var)",
241+
"Missing API secret key (set in profile or REDIS_CLOUD_API_SECRET env var)",
242242
);
243243
}
244244

0 commit comments

Comments
 (0)