From cbc9de6a4903e24ca3bc3d1f274b28ea670ee012 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sun, 26 May 2024 10:12:17 +0200 Subject: [PATCH] Make provider implementations public --- src/config_default_credentials.rs | 13 +++++++++++-- src/gcloud_authorized_user.rs | 6 ++++-- src/lib.rs | 10 +++++----- src/metadata_service_account.rs | 13 +++++++++++-- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/config_default_credentials.rs b/src/config_default_credentials.rs index 4fb360d..0912d40 100644 --- a/src/config_default_credentials.rs +++ b/src/config_default_credentials.rs @@ -12,15 +12,24 @@ use tracing::{debug, instrument, Level}; use crate::types::{HttpClient, Token}; use crate::{Error, TokenProvider}; +/// A token provider that uses the default user credentials +/// +/// Reads credentials from `.config/gcloud/application_default_credentials.json`. #[derive(Debug)] -pub(crate) struct ConfigDefaultCredentials { +pub struct ConfigDefaultCredentials { client: HttpClient, token: RwLock>, credentials: UserCredentials, } impl ConfigDefaultCredentials { - pub(crate) async fn new(client: &HttpClient) -> Result { + /// Check for user credentials in the default location and try to deserialize them + pub async fn new() -> Result { + let client = HttpClient::new()?; + Self::with_client(&client).await + } + + pub(crate) async fn with_client(client: &HttpClient) -> Result { debug!("try to load credentials from {}", USER_CREDENTIALS_PATH); let mut home = home::home_dir().ok_or(Error::Str("home directory not found"))?; home.push(USER_CREDENTIALS_PATH); diff --git a/src/gcloud_authorized_user.rs b/src/gcloud_authorized_user.rs index 7e54813..2ff424a 100644 --- a/src/gcloud_authorized_user.rs +++ b/src/gcloud_authorized_user.rs @@ -11,15 +11,17 @@ use which::which; use crate::types::Token; use crate::{Error, TokenProvider}; +/// A token provider that queries the `gcloud` CLI for access tokens #[derive(Debug)] -pub(crate) struct GCloudAuthorizedUser { +pub struct GCloudAuthorizedUser { gcloud: PathBuf, project_id: Option>, token: RwLock>, } impl GCloudAuthorizedUser { - pub(crate) async fn new() -> Result { + /// Check if `gcloud` is installed and logged in + pub async fn new() -> Result { debug!("try to print access token via `gcloud`"); let gcloud = which("gcloud").map_err(|_| Error::Str("`gcloud` binary not found"))?; let project_id = run(&gcloud, &["config", "get-value", "project"]).ok(); diff --git a/src/lib.rs b/src/lib.rs index 4922565..4164eea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,13 +95,13 @@ mod custom_service_account; pub use custom_service_account::CustomServiceAccount; mod config_default_credentials; -use config_default_credentials::ConfigDefaultCredentials; +pub use config_default_credentials::ConfigDefaultCredentials; mod metadata_service_account; -use metadata_service_account::MetadataServiceAccount; +pub use metadata_service_account::MetadataServiceAccount; mod gcloud_authorized_user; -use gcloud_authorized_user::GCloudAuthorizedUser; +pub use gcloud_authorized_user::GCloudAuthorizedUser; mod types; use types::HttpClient; @@ -127,7 +127,7 @@ pub async fn provider() -> Result, Error> { } let client = HttpClient::new()?; - let default_user_error = match ConfigDefaultCredentials::new(&client).await { + let default_user_error = match ConfigDefaultCredentials::with_client(&client).await { Ok(provider) => { debug!("using ConfigDefaultCredentials"); return Ok(Arc::new(provider)); @@ -135,7 +135,7 @@ pub async fn provider() -> Result, Error> { Err(e) => e, }; - let default_service_error = match MetadataServiceAccount::new(&client).await { + let default_service_error = match MetadataServiceAccount::with_client(&client).await { Ok(provider) => { debug!("using MetadataServiceAccount"); return Ok(Arc::new(provider)); diff --git a/src/metadata_service_account.rs b/src/metadata_service_account.rs index 1fbae1d..3cdefda 100644 --- a/src/metadata_service_account.rs +++ b/src/metadata_service_account.rs @@ -10,15 +10,24 @@ use tracing::{debug, instrument, Level}; use crate::types::{HttpClient, Token}; use crate::{Error, TokenProvider}; +/// A token provider that queries the GCP instance metadata server for access tokens +/// +/// See https://cloud.google.com/compute/docs/metadata/predefined-metadata-keys for details. #[derive(Debug)] -pub(crate) struct MetadataServiceAccount { +pub struct MetadataServiceAccount { client: HttpClient, project_id: Arc, token: RwLock>, } impl MetadataServiceAccount { - pub(crate) async fn new(client: &HttpClient) -> Result { + /// Check that the GCP instance metadata server is available and try to fetch a token + pub async fn new() -> Result { + let client = HttpClient::new()?; + Self::with_client(&client).await + } + + pub(crate) async fn with_client(client: &HttpClient) -> Result { debug!("try to fetch token from GCP instance metadata server"); let token = RwLock::new(Self::fetch_token(client).await?);