@@ -14,7 +14,6 @@ use figment::{providers::Env, Figment};
1414use serde:: { Deserialize , Deserializer } ;
1515use serde_json:: Value ;
1616use trace_propagation_style:: { deserialize_trace_propagation_style, TracePropagationStyle } ;
17- use tracing:: debug;
1817
1918use crate :: config:: {
2019 flush_strategy:: FlushStrategy ,
@@ -73,6 +72,15 @@ pub struct YamlLogsConfig {
7372#[ allow( clippy:: module_name_repetitions) ]
7473pub struct YamlConfig {
7574 pub logs_config : YamlLogsConfig ,
75+ pub proxy : YamlProxyConfig ,
76+ }
77+
78+ #[ derive( Debug , PartialEq , Deserialize , Clone , Default ) ]
79+ #[ serde( default ) ]
80+ #[ allow( clippy:: module_name_repetitions) ]
81+ pub struct YamlProxyConfig {
82+ pub https : Option < String > ,
83+ pub no_proxy : Option < Vec < String > > ,
7684}
7785
7886#[ derive( Debug , PartialEq , Deserialize , Clone ) ]
@@ -251,23 +259,33 @@ pub fn get_config(config_directory: &Path) -> Result<Config, ConfigError> {
251259 return Err ( ConfigError :: ParseError ( err. to_string ( ) ) ) ;
252260 }
253261 } ;
254-
255- // Prefer DD_PROXY_HTTPS over HTTPS_PROXY
256- // No else needed as HTTPS_PROXY is handled by reqwest and built into trace client
257- if let Ok ( https_proxy) = std:: env:: var ( "DD_PROXY_HTTPS" ) {
258- config. https_proxy = Some ( https_proxy) ;
259- }
260262 // Set site if empty
261263 if config. site . is_empty ( ) {
262264 config. site = "datadoghq.com" . to_string ( ) ;
263265 }
264- // TODO(astuyve)
265- // Bit of a hack as we're not checking individual privatelink setups
266- // potentially a user could use the proxy for logs and privatelink for APM
267- if std:: env:: var ( "NO_PROXY" ) . map_or ( false , |no_proxy| no_proxy. contains ( & config. site ) ) {
268- debug ! ( "NO_PROXY contains DD_SITE, disabling proxy" ) ;
269- config. https_proxy = None ;
266+
267+ // NOTE: Must happen after config.site is set
268+ // Prefer DD_PROXY_HTTPS over HTTPS_PROXY
269+ // No else needed as HTTPS_PROXY is handled by reqwest and built into trace client
270+ if let Ok ( https_proxy) = std:: env:: var ( "DD_PROXY_HTTPS" ) . or_else ( |_| {
271+ yaml_config
272+ . proxy
273+ . https
274+ . clone ( )
275+ . ok_or ( std:: env:: VarError :: NotPresent )
276+ } ) {
277+ if std:: env:: var ( "NO_PROXY" ) . map_or ( false , |no_proxy| no_proxy. contains ( & config. site ) )
278+ || yaml_config
279+ . proxy
280+ . no_proxy
281+ . map_or ( false , |no_proxy| no_proxy. contains ( & config. site ) )
282+ {
283+ config. https_proxy = None ;
284+ } else {
285+ config. https_proxy = Some ( https_proxy) ;
286+ }
270287 }
288+
271289 // Merge YAML nested fields
272290 //
273291 // Set logs_config_processing_rules if not defined in env
@@ -556,6 +574,47 @@ pub mod tests {
556574 } ) ;
557575 }
558576
577+ #[ test]
578+ fn test_proxy_yaml ( ) {
579+ figment:: Jail :: expect_with ( |jail| {
580+ jail. clear_env ( ) ;
581+ jail. create_file (
582+ "datadog.yaml" ,
583+ r"
584+ proxy:
585+ https: my-proxy:3128
586+ " ,
587+ ) ?;
588+
589+ let config = get_config ( Path :: new ( "" ) ) . expect ( "should parse weird proxy config" ) ;
590+ assert_eq ! ( config. https_proxy, Some ( "my-proxy:3128" . to_string( ) ) ) ;
591+ Ok ( ( ) )
592+ } ) ;
593+ }
594+
595+ #[ test]
596+ fn test_no_proxy_yaml ( ) {
597+ figment:: Jail :: expect_with ( |jail| {
598+ jail. clear_env ( ) ;
599+ jail. create_file (
600+ "datadog.yaml" ,
601+ r"
602+ proxy:
603+ https: my-proxy:3128
604+ no_proxy:
605+ - datadoghq.com
606+ " ,
607+ ) ?;
608+
609+ let config = get_config ( Path :: new ( "" ) ) . expect ( "should parse weird proxy config" ) ;
610+ assert_eq ! ( config. https_proxy, None ) ;
611+ // Assertion to ensure config.site runs before proxy
612+ // because we chenck that noproxy contains the site
613+ assert_eq ! ( config. site, "datadoghq.com" ) ;
614+ Ok ( ( ) )
615+ } ) ;
616+ }
617+
559618 #[ test]
560619 fn test_parse_flush_strategy_end ( ) {
561620 figment:: Jail :: expect_with ( |jail| {
0 commit comments