feat: Added typed errors to improve library DevX and removed now deprecated migrate command
Check / stable / fmt (push) Failing after 25s
Check / beta / clippy (push) Failing after 44s
Check / stable / clippy (push) Failing after 43s
Check / nightly / doc (push) Failing after 42s
Check / 1.89.0 / check (push) Failing after 45s
Test Suite / ubuntu / beta (push) Failing after 44s
Test Suite / ubuntu / stable (push) Failing after 44s
Test Suite / ubuntu / stable / coverage (push) Failing after 1m17s
Test Suite / macos-latest / stable (push) Has been cancelled
Test Suite / windows-latest / stable (push) Has been cancelled
Check / stable / fmt (push) Failing after 25s
Check / beta / clippy (push) Failing after 44s
Check / stable / clippy (push) Failing after 43s
Check / nightly / doc (push) Failing after 42s
Check / 1.89.0 / check (push) Failing after 45s
Test Suite / ubuntu / beta (push) Failing after 44s
Test Suite / ubuntu / stable (push) Failing after 44s
Test Suite / ubuntu / stable / coverage (push) Failing after 1m17s
Test Suite / macos-latest / stable (push) Has been cancelled
Test Suite / windows-latest / stable (push) Has been cancelled
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use crate::providers::SecretProvider;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use anyhow::anyhow;
|
||||
use gcloud_sdk::google::cloud::secretmanager::v1;
|
||||
use gcloud_sdk::google::cloud::secretmanager::v1::replication::Automatic;
|
||||
use gcloud_sdk::google::cloud::secretmanager::v1::secret_manager_service_client::SecretManagerServiceClient;
|
||||
@@ -15,8 +14,13 @@ use serde_with::skip_serializing_none;
|
||||
use v1::DeleteSecretRequest;
|
||||
use validator::Validate;
|
||||
|
||||
use crate::providers::SecretProvider;
|
||||
use crate::providers::error::{SecretError, classify_gcp_error};
|
||||
|
||||
type SecretsManagerClient = GoogleApi<SecretManagerServiceClient<GoogleAuthMiddleware>>;
|
||||
|
||||
const PROVIDER: &str = "gcp_secret_manager";
|
||||
|
||||
#[skip_serializing_none]
|
||||
/// Configuration for GCP Secret Manager provider
|
||||
/// See [GCP Secret Manager](https://cloud.google.com/secret-manager)
|
||||
@@ -48,8 +52,8 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
"GcpSecretManagerProvider"
|
||||
}
|
||||
|
||||
async fn get_secret(&self, key: &str) -> Result<String> {
|
||||
let secret_value = self
|
||||
async fn get_secret(&self, key: &str) -> Result<String, SecretError> {
|
||||
let response = self
|
||||
.get_client()
|
||||
.await?
|
||||
.get()
|
||||
@@ -60,20 +64,22 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
key
|
||||
),
|
||||
})
|
||||
.await?
|
||||
.into_inner()
|
||||
.payload
|
||||
.ok_or_else(|| anyhow!("Secret '{}' not found", key))?
|
||||
.data
|
||||
.ref_sensitive_value()
|
||||
.to_vec();
|
||||
let secret_string = String::from_utf8(secret_value)
|
||||
.with_context(|| format!("Invalid UTF-8 in secret '{})'", key))?;
|
||||
.await
|
||||
.map_err(|e| classify_gcp_error(e.into(), Some(key), "get_secret"))?
|
||||
.into_inner();
|
||||
let payload = response.payload.ok_or_else(|| SecretError::NotFound {
|
||||
key: key.to_string(),
|
||||
provider: PROVIDER,
|
||||
})?;
|
||||
let secret_value = payload.data.ref_sensitive_value().to_vec();
|
||||
let secret_string = String::from_utf8(secret_value).map_err(|_| {
|
||||
SecretError::Other(anyhow!("secret value is not valid UTF-8"))
|
||||
})?;
|
||||
|
||||
Ok(secret_string)
|
||||
}
|
||||
|
||||
async fn set_secret(&self, key: &str, value: &str) -> Result<()> {
|
||||
async fn set_secret(&self, key: &str, value: &str) -> Result<(), SecretError> {
|
||||
let parent = format!("projects/{}", self.gcp_project_id.as_ref().unwrap());
|
||||
let secret_name = format!("{}/secrets/{}", parent, key);
|
||||
let secret = Secret {
|
||||
@@ -96,9 +102,12 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
.await
|
||||
.map_err(|e| {
|
||||
if e.code() == Code::AlreadyExists {
|
||||
anyhow!("Secret already exists")
|
||||
SecretError::AlreadyExists {
|
||||
key: key.to_string(),
|
||||
provider: PROVIDER,
|
||||
}
|
||||
} else {
|
||||
e.into()
|
||||
classify_gcp_error(e.into(), Some(key), "set_secret")
|
||||
}
|
||||
})?;
|
||||
|
||||
@@ -113,12 +122,13 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
data_crc32c: Some(crc32c),
|
||||
}),
|
||||
})
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| classify_gcp_error(e.into(), Some(key), "set_secret"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_secret(&self, key: &str) -> Result<()> {
|
||||
async fn delete_secret(&self, key: &str) -> Result<(), SecretError> {
|
||||
let name = format!(
|
||||
"projects/{}/secrets/{}",
|
||||
self.gcp_project_id.as_ref().unwrap(),
|
||||
@@ -131,11 +141,12 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
name,
|
||||
etag: "".to_string(),
|
||||
})
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| classify_gcp_error(e.into(), Some(key), "delete_secret"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_secret(&self, key: &str, value: &str) -> Result<()> {
|
||||
async fn update_secret(&self, key: &str, value: &str) -> Result<(), SecretError> {
|
||||
let parent = format!(
|
||||
"projects/{}/secrets/{}",
|
||||
self.gcp_project_id.as_ref().unwrap(),
|
||||
@@ -154,12 +165,13 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
data_crc32c: Some(crc32c),
|
||||
}),
|
||||
})
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| classify_gcp_error(e.into(), Some(key), "update_secret"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_secrets(&self) -> Result<Vec<String>> {
|
||||
async fn list_secrets(&self) -> Result<Vec<String>, SecretError> {
|
||||
let request = ListSecretsRequest {
|
||||
parent: format!("projects/{}", self.gcp_project_id.as_ref().unwrap()),
|
||||
..Default::default()
|
||||
@@ -169,7 +181,8 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
.await?
|
||||
.get()
|
||||
.list_secrets(request)
|
||||
.await?
|
||||
.await
|
||||
.map_err(|e| classify_gcp_error(e.into(), None, "list_secrets"))?
|
||||
.into_inner()
|
||||
.secrets
|
||||
.iter()
|
||||
@@ -188,13 +201,17 @@ impl SecretProvider for GcpSecretManagerProvider {
|
||||
}
|
||||
|
||||
impl GcpSecretManagerProvider {
|
||||
async fn get_client(&self) -> Result<SecretsManagerClient> {
|
||||
async fn get_client(&self) -> Result<SecretsManagerClient, SecretError> {
|
||||
let client = GoogleApi::from_function(
|
||||
SecretManagerServiceClient::new,
|
||||
"https://secretmanager.googleapis.com",
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(|e| SecretError::AuthFailed {
|
||||
provider: PROVIDER,
|
||||
source: e.into(),
|
||||
})?;
|
||||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user