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

Configuration: support allowlists #2546

Merged
merged 7 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 0 additions & 5 deletions config/database.yml

This file was deleted.

21 changes: 19 additions & 2 deletions lib/new_relic/agent/configuration/default_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,24 @@ def default_values
result
end

def self.default_settings(key)
::NewRelic::Agent::Configuration::DEFAULTS[key]
end

def self.value_from_defaults(key, subkey)
default_settings(key)&.send(:[], subkey)
end

def self.allowlist_for(key)
value_from_defaults(key, :allowlist)
end

def self.default_for(key)
value_from_defaults(key, :default)
end

def self.transform_for(key)
default_settings = ::NewRelic::Agent::Configuration::DEFAULTS[key]
default_settings[:transform] if default_settings
value_from_defaults(key, :transform)
end

def self.config_search_paths # rubocop:disable Metrics/AbcSize
Expand Down Expand Up @@ -800,6 +815,7 @@ def self.enforce_fallback(allowed_values: nil, fallback: nil)
:public => true,
:type => String,
:allowed_from_server => false,
:allowlist => %w[debug info warn error fatal unknown],
:description => <<~DESCRIPTION
Sets the minimum level a log event must have to be forwarded to New Relic.

Expand Down Expand Up @@ -2263,6 +2279,7 @@ def self.enforce_fallback(allowed_values: nil, fallback: nil)
:public => true,
:type => Symbol,
:allowed_from_server => false,
:allowlist => %i[none low medium high],
:external => :infinite_tracing,
:description => <<~DESC
Configure the compression level for data sent to the trace observer.
Expand Down
21 changes: 19 additions & 2 deletions lib/new_relic/agent/configuration/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,11 @@ def evaluate_procs(value)
end

def evaluate_and_apply_transformations(key, value)
apply_transformations(key, evaluate_procs(value))
evaluated = evaluate_procs(value)
default = enforce_allowlist(key, evaluated)
return default if default

apply_transformations(key, evaluated)
end

def apply_transformations(key, value)
Expand All @@ -154,8 +158,21 @@ def apply_transformations(key, value)
end
end

def enforce_allowlist(key, value)
return unless allowlist = default_source.allowlist_for(key)
return if allowlist.include?(value)

default = default_source.default_for(key)
::NewRelic::Agent.logger.warn "Invalid value '#{value}' for #{key}, applying default value of '#{default}'"
fallwith marked this conversation as resolved.
Show resolved Hide resolved
default
end

def transform_from_default(key)
::NewRelic::Agent::Configuration::DefaultSource.transform_for(key)
default_source.transform_for(key)
end

def default_source
::NewRelic::Agent::Configuration::DefaultSource
end

def register_callback(key, &proc)
Expand Down
18 changes: 18 additions & 0 deletions test/new_relic/agent/configuration/default_source_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,24 @@ def test_convert_to_hash_raises_error_with_wrong_data_type
assert_raises(ArgumentError) { DefaultSource.convert_to_hash(value) }
end

def test_allowlist_permits_valid_values
valid_value = 'info'
key = :'application_logging.forwarding.log_level'

with_config(key => valid_value) do
assert_equal valid_value, NewRelic::Agent.config[key]
end
end

def test_allowlist_blocks_invalid_values_and_uses_a_default
key = :'application_logging.forwarding.log_level'
default = ::NewRelic::Agent::Configuration::DefaultSource.default_for(key)

with_config(key => 'bogus') do
assert_equal default, NewRelic::Agent.config[key]
end
end

def get_config_value_class(value)
type = value.class

Expand Down