aws_config/default_provider/
use_dual_stack.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use crate::environment::parse_bool;
7use crate::provider_config::ProviderConfig;
8use aws_runtime::env_config::EnvConfigValue;
9use aws_smithy_types::error::display::DisplayErrorContext;
10
11mod env {
12    pub(super) const USE_DUAL_STACK: &str = "AWS_USE_DUALSTACK_ENDPOINT";
13}
14
15mod profile_key {
16    pub(super) const USE_DUAL_STACK: &str = "use_dualstack_endpoint";
17}
18
19/// Load the value for "use dual-stack"
20///
21/// This checks the following sources:
22/// 1. The environment variable `AWS_USE_DUALSTACK_ENDPOINT=true/false`
23/// 2. The profile key `use_dualstack_endpoint=true/false`
24///
25/// If invalid values are found, the provider will return `None` and an error will be logged.
26pub async fn use_dual_stack_provider(provider_config: &ProviderConfig) -> Option<bool> {
27    let env = provider_config.env();
28    let profiles = provider_config.profile().await;
29
30    EnvConfigValue::new()
31        .env(env::USE_DUAL_STACK)
32        .profile(profile_key::USE_DUAL_STACK)
33        .validate(&env, profiles, parse_bool)
34        .map_err(
35            |err| tracing::warn!(err = %DisplayErrorContext(&err), "invalid value for dual-stack setting"),
36        )
37        .unwrap_or(None)
38}
39
40#[cfg(test)]
41mod test {
42    use crate::default_provider::use_dual_stack::use_dual_stack_provider;
43    #[allow(deprecated)]
44    use crate::profile::profile_file::{ProfileFileKind, ProfileFiles};
45    use crate::provider_config::ProviderConfig;
46    use aws_types::os_shim_internal::{Env, Fs};
47    use tracing_test::traced_test;
48
49    #[tokio::test]
50    #[traced_test]
51    async fn log_error_on_invalid_value() {
52        let conf = ProviderConfig::empty().with_env(Env::from_slice(&[(
53            "AWS_USE_DUALSTACK_ENDPOINT",
54            "not-a-boolean",
55        )]));
56        assert_eq!(use_dual_stack_provider(&conf).await, None);
57        assert!(logs_contain("invalid value for dual-stack setting"));
58        assert!(logs_contain("AWS_USE_DUALSTACK_ENDPOINT"));
59    }
60
61    #[tokio::test]
62    #[traced_test]
63    async fn environment_priority() {
64        let conf = ProviderConfig::empty()
65            .with_env(Env::from_slice(&[("AWS_USE_DUALSTACK_ENDPOINT", "TRUE")]))
66            .with_profile_config(
67                Some(
68                    #[allow(deprecated)]
69                    ProfileFiles::builder()
70                        .with_file(
71                            #[allow(deprecated)]
72                            ProfileFileKind::Config,
73                            "conf",
74                        )
75                        .build(),
76                ),
77                None,
78            )
79            .with_fs(Fs::from_slice(&[(
80                "conf",
81                "[default]\nuse_dualstack_endpoint = false",
82            )]));
83        assert_eq!(use_dual_stack_provider(&conf).await, Some(true));
84    }
85
86    #[tokio::test]
87    #[traced_test]
88    async fn profile_works() {
89        let conf = ProviderConfig::empty()
90            .with_profile_config(
91                Some(
92                    #[allow(deprecated)]
93                    ProfileFiles::builder()
94                        .with_file(
95                            #[allow(deprecated)]
96                            ProfileFileKind::Config,
97                            "conf",
98                        )
99                        .build(),
100                ),
101                None,
102            )
103            .with_fs(Fs::from_slice(&[(
104                "conf",
105                "[default]\nuse_dualstack_endpoint = false",
106            )]));
107        assert_eq!(use_dual_stack_provider(&conf).await, Some(false));
108    }
109}