From 6ada623a264d8556414b496050983cf2a286ab4b Mon Sep 17 00:00:00 2001 From: Ivo Anjo Date: Thu, 2 Jan 2025 16:23:53 +0000 Subject: [PATCH] Move url building behavior from `AgentBaseUrl` to `AgentSettings` This is preparation to also share this behavior with profiling. --- .../configuration/agent_settings_resolver.rb | 18 ++++++ .../core/crashtracking/agent_base_url.rb | 14 +---- .../configuration/agent_settings_resolver.rbs | 7 +++ .../agent_settings_resolver_spec.rb | 57 +++++++++++++++++++ .../core/crashtracking/agent_base_url_spec.rb | 25 ++------ 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/lib/datadog/core/configuration/agent_settings_resolver.rb b/lib/datadog/core/configuration/agent_settings_resolver.rb index 3d407ce1afb..424f47c331e 100644 --- a/lib/datadog/core/configuration/agent_settings_resolver.rb +++ b/lib/datadog/core/configuration/agent_settings_resolver.rb @@ -32,8 +32,26 @@ def initialize(adapter: nil, ssl: nil, hostname: nil, port: nil, uds_path: nil, @timeout_seconds = timeout_seconds freeze end + + def url + case adapter + when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER + hostname = self.hostname + hostname = "[#{hostname}]" if hostname =~ IPV6_REGEXP + "#{ssl ? 'https' : 'http'}://#{hostname}:#{port}/" + when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER + "unix://#{uds_path}" + else + raise ArgumentError, "Unexpected adapter: #{adapter}" + end + end end + # IPv6 regular expression from + # https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses + # Does not match IPv4 addresses. + IPV6_REGEXP = /\A(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\z)/.freeze # rubocop:disable Layout/LineLength + def self.call(settings, logger: Datadog.logger) new(settings, logger: logger).send(:call) end diff --git a/lib/datadog/core/crashtracking/agent_base_url.rb b/lib/datadog/core/crashtracking/agent_base_url.rb index 74b59a1cda5..20a9a55129b 100644 --- a/lib/datadog/core/crashtracking/agent_base_url.rb +++ b/lib/datadog/core/crashtracking/agent_base_url.rb @@ -7,20 +7,8 @@ module Core module Crashtracking # This module provides a method to resolve the base URL of the agent module AgentBaseUrl - # IPv6 regular expression from - # https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses - # Does not match IPv4 addresses. - IPV6_REGEXP = /\A(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\z)/.freeze # rubocop:disable Layout/LineLength - def self.resolve(agent_settings) - case agent_settings.adapter - when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER - hostname = agent_settings.hostname - hostname = "[#{hostname}]" if hostname =~ IPV6_REGEXP - "#{agent_settings.ssl ? 'https' : 'http'}://#{hostname}:#{agent_settings.port}/" - when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER - "unix://#{agent_settings.uds_path}" - end + agent_settings.url end end end diff --git a/sig/datadog/core/configuration/agent_settings_resolver.rbs b/sig/datadog/core/configuration/agent_settings_resolver.rbs index a4ea2830ddb..e3a2472abf4 100644 --- a/sig/datadog/core/configuration/agent_settings_resolver.rbs +++ b/sig/datadog/core/configuration/agent_settings_resolver.rbs @@ -11,6 +11,8 @@ module Datadog attr_reader port: untyped attr_reader uds_path: untyped attr_reader timeout_seconds: untyped + + def url: () -> ::String end @settings: untyped @@ -24,6 +26,11 @@ module Datadog @mixed_http_and_uds: untyped @parsed_url: untyped + # IPv6 regular expression from + # https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses + # Does not match IPv4 addresses. + IPV6_REGEXP: ::Regexp + def self.call: (untyped settings, ?logger: untyped) -> untyped private diff --git a/spec/datadog/core/configuration/agent_settings_resolver_spec.rb b/spec/datadog/core/configuration/agent_settings_resolver_spec.rb index ef2a6766ea1..c057e520739 100644 --- a/spec/datadog/core/configuration/agent_settings_resolver_spec.rb +++ b/spec/datadog/core/configuration/agent_settings_resolver_spec.rb @@ -803,4 +803,61 @@ end end end + + describe 'url' do + context 'when using HTTP adapter' do + before do + datadog_settings.agent.host = 'example.com' + datadog_settings.agent.port = 8080 + end + + context 'when SSL is enabled' do + before { datadog_settings.agent.use_ssl = true } + + it 'returns the correct base URL' do + expect(resolver.url).to eq('https://example.com:8080/') + end + end + + context 'when SSL is disabled' do + before { datadog_settings.agent.use_ssl = false } + + it 'returns the correct base URL' do + expect(resolver.url).to eq('http://example.com:8080/') + end + end + + context 'when hostname is an IPv4 address' do + before { datadog_settings.agent.host = '1.2.3.4' } + + it 'returns the correct base URL' do + expect(resolver.url).to eq('http://1.2.3.4:8080/') + end + end + + context 'when hostname is an IPv6 address' do + before { datadog_settings.agent.host = '1234:1234::1' } + + it 'returns the correct base URL' do + expect(resolver.url).to eq('http://[1234:1234::1]:8080/') + end + end + end + + context 'when using UnixSocket adapter' do + before { datadog_settings.agent.uds_path = '/var/run/datadog.sock' } + + it 'returns the correct base URL' do + expect(resolver.url).to eq('unix:///var/run/datadog.sock') + end + end + + context 'when using an unknown adapter' do + it 'raises an exception' do + agent_settings = Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new(adapter: :unknown) + + expect { agent_settings.url }.to raise_error(ArgumentError, /Unexpected adapter/) + end + end + end end diff --git a/spec/datadog/core/crashtracking/agent_base_url_spec.rb b/spec/datadog/core/crashtracking/agent_base_url_spec.rb index 407b74daf26..4a8145208cf 100644 --- a/spec/datadog/core/crashtracking/agent_base_url_spec.rb +++ b/spec/datadog/core/crashtracking/agent_base_url_spec.rb @@ -8,8 +8,7 @@ context 'when using HTTP adapter' do context 'when SSL is enabled' do let(:agent_settings) do - instance_double( - Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, + Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new( adapter: Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER, ssl: true, hostname: 'example.com', @@ -24,8 +23,7 @@ context 'when SSL is disabled' do let(:agent_settings) do - instance_double( - Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, + Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new( adapter: Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER, ssl: false, hostname: 'example.com', @@ -40,8 +38,7 @@ context 'when hostname is an IPv4 address' do let(:agent_settings) do - instance_double( - Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, + Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new( adapter: Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER, ssl: false, hostname: '1.2.3.4', @@ -56,8 +53,7 @@ context 'when hostname is an IPv6 address' do let(:agent_settings) do - instance_double( - Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, + Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new( adapter: Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER, ssl: false, hostname: '1234:1234::1', @@ -73,8 +69,7 @@ context 'when using UnixSocket adapter' do let(:agent_settings) do - instance_double( - Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, + Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings.new( adapter: Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER, uds_path: '/var/run/datadog.sock' ) @@ -84,15 +79,5 @@ expect(described_class.resolve(agent_settings)).to eq('unix:///var/run/datadog.sock') end end - - context 'when using unknownm adapter' do - let(:agent_settings) do - instance_double(Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, adapter: 'unknown') - end - - it 'returns nil' do - expect(described_class.resolve(agent_settings)).to be_nil - end - end end end