Make `SCCACHE_S3_USE_SSL` optional

so that `SCCACHE_ENDPOINT` alone can control https or http scheme
This commit is contained in:
messense 2022-11-15 18:17:01 +08:00 коммит произвёл Sylvestre Ledru
Родитель 49e665f3fc
Коммит a02b256c69
3 изменённых файлов: 42 добавлений и 20 удалений

Просмотреть файл

@ -196,7 +196,7 @@ Credentials are resolved using the default AWS provider chain, including the `AW
If you do not want to use credentials at all, you can set the `SCCACHE_S3_NO_CREDENTIALS` environment variable. This requires the bucket to allow public readonly access, and can be useful to implement a readonly cache for pull requests, which typically can't be given access to credentials for security reasons.
You can configure the region using the `SCCACHE_REGION` environment variable, or specify the `region` key in `~/.aws/credentials`. Alternatively you can specify the endpoint URL using the `SCCACHE_ENDPOINT` environment variable. To connect to a minio storage for example you can set `SCCACHE_ENDPOINT=<ip>:<port>`. If your endpoint requires TLS, set `SCCACHE_S3_USE_SSL=true`.
You can configure the region using the `SCCACHE_REGION` environment variable, or specify the `region` key in `~/.aws/credentials`. Alternatively you can specify the endpoint URL using the `SCCACHE_ENDPOINT` environment variable. To connect to a minio storage for example you can set `SCCACHE_ENDPOINT=<ip>:<port>`. If your endpoint requires TLS, set `SCCACHE_S3_USE_SSL=true`. If you don't need a secure network layer, http might be better for performance.
You can also define a prefix that will be prepended to the keys of all cache objects created and read within the S3 bucket, effectively creating a scope. To do that use the `SCCACHE_S3_KEY_PREFIX` environment variable. This can be useful when sharing a bucket with another application.

53
src/cache/s3.rs поставляемый
Просмотреть файл

@ -37,7 +37,7 @@ impl S3Cache {
key_prefix: &str,
no_credentials: bool,
endpoint: Option<&str>,
use_ssl: bool,
use_ssl: Option<bool>,
) -> Result<S3Cache> {
Ok(S3Cache {
key_prefix: key_prefix.to_owned(),
@ -101,6 +101,29 @@ fn normalize_key(prefix: &str, key: &str) -> String {
)
}
fn endpoint_resolver(endpoint: &str, use_ssl: Option<bool>) -> Endpoint {
let endpoint_uri: http::Uri = endpoint.try_into().unwrap();
let mut parts = endpoint_uri.into_parts();
match use_ssl {
Some(true) => {
parts.scheme = Some(http::uri::Scheme::HTTPS);
}
Some(false) => {
parts.scheme = Some(http::uri::Scheme::HTTP);
}
None => {
if parts.scheme.is_none() {
parts.scheme = Some(http::uri::Scheme::HTTP);
}
}
}
// path_and_query is required when scheme is set
if parts.path_and_query.is_none() {
parts.path_and_query = Some(http::uri::PathAndQuery::from_static("/"));
}
Endpoint::mutable(http::Uri::from_parts(parts).unwrap())
}
struct S3Client {
bucket: String,
config: Config,
@ -111,7 +134,7 @@ impl S3Client {
bucket: &str,
region: Option<&str>,
endpoint: Option<&str>,
use_ssl: bool,
use_ssl: Option<bool>,
) -> Result<S3Client> {
let region_provider =
RegionProviderChain::first_try(region.map(|r| Region::new(r.to_owned())))
@ -120,19 +143,7 @@ impl S3Client {
let shared_config = aws_config::from_env().region(region_provider).load().await;
let mut builder = aws_sdk_s3::config::Builder::from(&shared_config);
if let Some(endpoint) = endpoint {
let endpoint_uri: http::Uri = endpoint.try_into().unwrap();
let mut parts = endpoint_uri.into_parts();
if use_ssl {
parts.scheme = Some(http::uri::Scheme::HTTPS);
} else {
parts.scheme = Some(http::uri::Scheme::HTTP);
}
// path_and_query is required when scheme is set
if parts.path_and_query.is_none() {
parts.path_and_query = Some(http::uri::PathAndQuery::from_static("/"));
}
builder =
builder.endpoint_resolver(Endpoint::mutable(http::Uri::from_parts(parts).unwrap()));
builder = builder.endpoint_resolver(endpoint_resolver(endpoint, use_ssl));
}
let config = builder.build();
@ -203,4 +214,16 @@ mod test {
"prefix/0/1/2/0123456789abcdef0123456789abcdef"
);
}
#[test]
fn test_endpoint_resolver() {
let endpoint = endpoint_resolver("s3-us-east-1.amazonaws.com", None);
assert_eq!(endpoint.uri().scheme_str(), Some("http"));
let endpoint = endpoint_resolver("s3-us-east-1.amazonaws.com", Some(true));
assert_eq!(endpoint.uri().scheme_str(), Some("https"));
let endpoint = endpoint_resolver("s3-us-east-1.amazonaws.com", Some(false));
assert_eq!(endpoint.uri().scheme_str(), Some("http"));
}
}

Просмотреть файл

@ -207,7 +207,7 @@ pub struct S3CacheConfig {
pub key_prefix: String,
pub no_credentials: bool,
pub endpoint: Option<String>,
pub use_ssl: bool,
pub use_ssl: Option<bool>,
}
#[derive(Debug, PartialEq, Eq)]
@ -460,8 +460,7 @@ fn config_from_env() -> Result<EnvConfig> {
let no_credentials = env::var("SCCACHE_S3_NO_CREDENTIALS").ok().is_some();
let use_ssl = env::var("SCCACHE_S3_USE_SSL")
.ok()
.filter(|value| value != "off")
.is_some();
.map(|value| value != "off");
let endpoint = env::var("SCCACHE_ENDPOINT").ok();
let key_prefix = env::var("SCCACHE_S3_KEY_PREFIX")
.ok()
@ -1061,7 +1060,7 @@ no_credentials = true
bucket: "name".to_owned(),
region: Some("us-east-2".to_owned()),
endpoint: Some("s3-us-east-1.amazonaws.com".to_owned()),
use_ssl: true,
use_ssl: Some(true),
key_prefix: "s3prefix".into(),
no_credentials: true,
}),