Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting ClientOptions with Options API #4202

Merged
merged 2 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions object_store/src/aws/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,9 @@ pub enum AmazonS3ConfigKey {
/// - `aws_profile`
/// - `profile`
Profile,

/// Client options
Client(ClientConfigKey),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice way to keep everything in one property bag ❤️

}

impl AsRef<str> for AmazonS3ConfigKey {
Expand All @@ -622,6 +625,7 @@ impl AsRef<str> for AmazonS3ConfigKey {
Self::Profile => "aws_profile",
Self::UnsignedPayload => "aws_unsigned_payload",
Self::Checksum => "aws_checksum_algorithm",
Self::Client(opt) => opt.as_ref(),
}
}
}
Expand Down Expand Up @@ -652,7 +656,12 @@ impl FromStr for AmazonS3ConfigKey {
"aws_metadata_endpoint" | "metadata_endpoint" => Ok(Self::MetadataEndpoint),
"aws_unsigned_payload" | "unsigned_payload" => Ok(Self::UnsignedPayload),
"aws_checksum_algorithm" | "checksum_algorithm" => Ok(Self::Checksum),
_ => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
// Backwards compatibility
"aws_allow_http" => Ok(Self::Client(ClientConfigKey::AllowHttp)),
_ => match s.parse() {
Ok(key) => Ok(Self::Client(key)),
Err(_) => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
},
}
}
}
Expand Down Expand Up @@ -688,9 +697,7 @@ impl AmazonS3Builder {
for (os_key, os_value) in std::env::vars_os() {
if let (Some(key), Some(value)) = (os_key.to_str(), os_value.to_str()) {
if key.starts_with("AWS_") {
if let Ok(config_key) =
AmazonS3ConfigKey::from_str(&key.to_ascii_lowercase())
{
if let Ok(config_key) = key.to_ascii_lowercase().parse() {
builder = builder.with_config(config_key, value);
}
}
Expand All @@ -706,12 +713,6 @@ impl AmazonS3Builder {
Some(format!("{METADATA_ENDPOINT}{metadata_relative_uri}"));
}

if let Ok(text) = std::env::var("AWS_ALLOW_HTTP") {
builder.client_options = builder
.client_options
.with_config(ClientConfigKey::AllowHttp, text);
}

builder
}

Expand Down Expand Up @@ -770,6 +771,9 @@ impl AmazonS3Builder {
AmazonS3ConfigKey::Checksum => {
self.checksum_algorithm = Some(ConfigValue::Deferred(value.into()))
}
AmazonS3ConfigKey::Client(key) => {
self.client_options = self.client_options.with_config(key, value)
}
};
self
}
Expand Down Expand Up @@ -834,6 +838,7 @@ impl AmazonS3Builder {
AmazonS3ConfigKey::Checksum => {
self.checksum_algorithm.as_ref().map(ToString::to_string)
}
AmazonS3ConfigKey::Client(key) => self.client_options.get_config_value(key),
}
}

Expand Down
25 changes: 15 additions & 10 deletions object_store/src/azure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,9 @@ pub enum AzureConfigKey {
/// - `azure_use_azure_cli`
/// - `use_azure_cli`
UseAzureCli,

/// Client options
Client(ClientConfigKey),
}

impl AsRef<str> for AzureConfigKey {
Expand All @@ -577,6 +580,7 @@ impl AsRef<str> for AzureConfigKey {
Self::MsiResourceId => "azure_msi_resource_id",
Self::FederatedTokenFile => "azure_federated_token_file",
Self::UseAzureCli => "azure_use_azure_cli",
Self::Client(key) => key.as_ref(),
}
}
}
Expand Down Expand Up @@ -621,7 +625,12 @@ impl FromStr for AzureConfigKey {
Ok(Self::FederatedTokenFile)
}
"azure_use_azure_cli" | "use_azure_cli" => Ok(Self::UseAzureCli),
_ => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
// Backwards compatibility
"azure_allow_http" => Ok(Self::Client(ClientConfigKey::AllowHttp)),
_ => match s.parse() {
Ok(key) => Ok(Self::Client(key)),
Err(_) => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
},
}
}
}
Expand Down Expand Up @@ -664,21 +673,13 @@ impl MicrosoftAzureBuilder {
for (os_key, os_value) in std::env::vars_os() {
if let (Some(key), Some(value)) = (os_key.to_str(), os_value.to_str()) {
if key.starts_with("AZURE_") {
if let Ok(config_key) =
AzureConfigKey::from_str(&key.to_ascii_lowercase())
{
if let Ok(config_key) = key.to_ascii_lowercase().parse() {
builder = builder.with_config(config_key, value);
}
}
}
}

if let Ok(text) = std::env::var("AZURE_ALLOW_HTTP") {
builder.client_options = builder
.client_options
.with_config(ClientConfigKey::AllowHttp, text)
}

if let Ok(text) = std::env::var(MSI_ENDPOINT_ENV_KEY) {
builder = builder.with_msi_endpoint(text);
}
Expand Down Expand Up @@ -731,6 +732,9 @@ impl MicrosoftAzureBuilder {
}
AzureConfigKey::UseAzureCli => self.use_azure_cli.parse(value),
AzureConfigKey::UseEmulator => self.use_emulator.parse(value),
AzureConfigKey::Client(key) => {
self.client_options = self.client_options.with_config(key, value)
}
};
self
}
Expand Down Expand Up @@ -786,6 +790,7 @@ impl MicrosoftAzureBuilder {
AzureConfigKey::MsiResourceId => self.msi_resource_id.clone(),
AzureConfigKey::FederatedTokenFile => self.federated_token_file.clone(),
AzureConfigKey::UseAzureCli => Some(self.use_azure_cli.to_string()),
AzureConfigKey::Client(key) => self.client_options.get_config_value(key),
}
}

Expand Down
23 changes: 23 additions & 0 deletions object_store/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use reqwest::header::{HeaderMap, HeaderValue};
use reqwest::{Client, ClientBuilder, Proxy};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str::FromStr;
use std::time::Duration;

use crate::path::Path;
Expand All @@ -53,6 +54,28 @@ pub enum ClientConfigKey {
AllowHttp,
}

impl AsRef<str> for ClientConfigKey {
fn as_ref(&self) -> &str {
match self {
Self::AllowHttp => "allow_http",
}
}
}

impl FromStr for ClientConfigKey {
type Err = super::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"allow_http" => Ok(Self::AllowHttp),
_ => Err(super::Error::UnknownConfigurationKey {
store: "HTTP",
key: s.into(),
}),
}
}
}

/// HTTP client configuration for remote object stores
#[derive(Debug, Clone, Default)]
pub struct ClientOptions {
Expand Down
18 changes: 14 additions & 4 deletions object_store/src/gcp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use url::Url;

use crate::client::pagination::stream_paginated;
use crate::client::retry::RetryExt;
use crate::client::ClientConfigKey;
use crate::{
client::token::TokenCache,
multipart::{CloudMultiPartUpload, CloudMultiPartUploadImpl, UploadPart},
Expand Down Expand Up @@ -829,6 +830,9 @@ pub enum GoogleConfigKey {
///
/// See [`GoogleCloudStorageBuilder::with_application_credentials`].
ApplicationCredentials,

/// Client options
Client(ClientConfigKey),
}

impl AsRef<str> for GoogleConfigKey {
Expand All @@ -838,6 +842,7 @@ impl AsRef<str> for GoogleConfigKey {
Self::ServiceAccountKey => "google_service_account_key",
Self::Bucket => "google_bucket",
Self::ApplicationCredentials => "google_application_credentials",
Self::Client(key) => key.as_ref(),
}
}
}
Expand All @@ -858,7 +863,10 @@ impl FromStr for GoogleConfigKey {
Ok(Self::Bucket)
}
"google_application_credentials" => Ok(Self::ApplicationCredentials),
_ => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
_ => match s.parse() {
Ok(key) => Ok(Self::Client(key)),
Err(_) => Err(Error::UnknownConfigurationKey { key: s.into() }.into()),
},
}
}
}
Expand Down Expand Up @@ -911,9 +919,7 @@ impl GoogleCloudStorageBuilder {
for (os_key, os_value) in std::env::vars_os() {
if let (Some(key), Some(value)) = (os_key.to_str(), os_value.to_str()) {
if key.starts_with("GOOGLE_") {
if let Ok(config_key) =
GoogleConfigKey::from_str(&key.to_ascii_lowercase())
{
if let Ok(config_key) = key.to_ascii_lowercase().parse() {
builder = builder.with_config(config_key, value);
}
}
Expand Down Expand Up @@ -957,6 +963,9 @@ impl GoogleCloudStorageBuilder {
GoogleConfigKey::ApplicationCredentials => {
self.application_credentials_path = Some(value.into())
}
GoogleConfigKey::Client(key) => {
self.client_options = self.client_options.with_config(key, value)
}
};
self
}
Expand Down Expand Up @@ -1005,6 +1014,7 @@ impl GoogleCloudStorageBuilder {
GoogleConfigKey::ApplicationCredentials => {
self.application_credentials_path.clone()
}
GoogleConfigKey::Client(key) => self.client_options.get_config_value(key),
}
}

Expand Down