contrast-agent 5.1.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_kernel/cs__assess_kernel.c +7 -4
  3. data/ext/cs__assess_module/cs__assess_module.c +7 -7
  4. data/ext/cs__common/cs__common.c +4 -0
  5. data/ext/cs__common/cs__common.h +1 -0
  6. data/ext/cs__contrast_patch/cs__contrast_patch.c +52 -27
  7. data/ext/cs__contrast_patch/cs__contrast_patch.h +2 -0
  8. data/ext/cs__scope/cs__scope.c +747 -0
  9. data/ext/cs__scope/cs__scope.h +88 -0
  10. data/ext/cs__scope/extconf.rb +5 -0
  11. data/lib/contrast/agent/assess/contrast_event.rb +20 -13
  12. data/lib/contrast/agent/assess/contrast_object.rb +4 -1
  13. data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -5
  14. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +2 -0
  15. data/lib/contrast/agent/assess/policy/trigger_method.rb +4 -1
  16. data/lib/contrast/agent/assess/rule/response/{autocomplete_rule.rb → auto_complete_rule.rb} +4 -3
  17. data/lib/contrast/agent/assess/rule/response/base_rule.rb +12 -79
  18. data/lib/contrast/agent/assess/rule/response/body_rule.rb +109 -0
  19. data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +157 -0
  20. data/lib/contrast/agent/assess/rule/response/click_jacking_header_rule.rb +26 -0
  21. data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +14 -15
  22. data/lib/contrast/agent/assess/rule/response/csp_header_missing_rule.rb +5 -25
  23. data/lib/contrast/agent/assess/rule/response/framework/rails_support.rb +29 -0
  24. data/lib/contrast/agent/assess/rule/response/header_rule.rb +70 -0
  25. data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +12 -36
  26. data/lib/contrast/agent/assess/rule/response/parameters_pollution_rule.rb +2 -1
  27. data/lib/contrast/agent/assess/rule/response/x_content_type_header_rule.rb +26 -0
  28. data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +36 -0
  29. data/lib/contrast/agent/middleware.rb +1 -0
  30. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +1 -3
  31. data/lib/contrast/agent/patching/policy/patch.rb +2 -6
  32. data/lib/contrast/agent/patching/policy/patcher.rb +1 -1
  33. data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +94 -0
  34. data/lib/contrast/agent/protect/rule/base.rb +28 -1
  35. data/lib/contrast/agent/protect/rule/base_service.rb +10 -1
  36. data/lib/contrast/agent/protect/rule/cmd_injection.rb +2 -0
  37. data/lib/contrast/agent/protect/rule/deserialization.rb +6 -0
  38. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +5 -1
  39. data/lib/contrast/agent/protect/rule/no_sqli.rb +1 -0
  40. data/lib/contrast/agent/protect/rule/path_traversal.rb +1 -0
  41. data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +124 -0
  42. data/lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb +121 -0
  43. data/lib/contrast/agent/protect/rule/sqli.rb +33 -0
  44. data/lib/contrast/agent/protect/rule/xxe.rb +4 -0
  45. data/lib/contrast/agent/reporting/input_analysis/input_analysis.rb +44 -0
  46. data/lib/contrast/agent/reporting/input_analysis/input_analysis_result.rb +115 -0
  47. data/lib/contrast/agent/reporting/input_analysis/input_type.rb +44 -0
  48. data/lib/contrast/agent/reporting/input_analysis/score_level.rb +21 -0
  49. data/lib/contrast/agent/reporting/report.rb +1 -0
  50. data/lib/contrast/agent/reporting/reporter.rb +8 -1
  51. data/lib/contrast/agent/reporting/reporting_events/finding.rb +69 -36
  52. data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +88 -59
  53. data/lib/contrast/agent/reporting/reporting_events/{finding_object.rb → finding_event_object.rb} +24 -20
  54. data/lib/contrast/agent/reporting/reporting_events/finding_event_parent_object.rb +39 -0
  55. data/lib/contrast/agent/reporting/reporting_events/finding_event_property.rb +40 -0
  56. data/lib/contrast/agent/reporting/reporting_events/{finding_signature.rb → finding_event_signature.rb} +29 -24
  57. data/lib/contrast/agent/reporting/reporting_events/finding_event_source.rb +12 -8
  58. data/lib/contrast/agent/reporting/reporting_events/{finding_stack.rb → finding_event_stack.rb} +23 -19
  59. data/lib/contrast/agent/reporting/reporting_events/{finding_taint_range.rb → finding_event_taint_range.rb} +17 -15
  60. data/lib/contrast/agent/reporting/reporting_events/finding_request.rb +26 -53
  61. data/lib/contrast/agent/reporting/reporting_events/poll.rb +29 -0
  62. data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +5 -4
  63. data/lib/contrast/agent/reporting/reporting_events/route_discovery.rb +1 -0
  64. data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +1 -1
  65. data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +10 -3
  66. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +0 -1
  67. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +1 -0
  68. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +28 -20
  69. data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +1 -1
  70. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +13 -1
  71. data/lib/contrast/agent/request_context.rb +6 -1
  72. data/lib/contrast/agent/request_context_extend.rb +85 -21
  73. data/lib/contrast/agent/scope.rb +102 -107
  74. data/lib/contrast/agent/service_heartbeat.rb +45 -2
  75. data/lib/contrast/agent/version.rb +1 -1
  76. data/lib/contrast/api/decorators/bot_blocker.rb +37 -0
  77. data/lib/contrast/api/decorators/ip_denylist.rb +37 -0
  78. data/lib/contrast/api/decorators/rasp_rule_sample.rb +29 -0
  79. data/lib/contrast/api/decorators/user_input.rb +11 -1
  80. data/lib/contrast/api/decorators/virtual_patch.rb +34 -0
  81. data/lib/contrast/components/logger.rb +5 -0
  82. data/lib/contrast/components/protect.rb +4 -2
  83. data/lib/contrast/components/scope.rb +98 -91
  84. data/lib/contrast/config/agent_configuration.rb +58 -12
  85. data/lib/contrast/config/api_configuration.rb +100 -12
  86. data/lib/contrast/config/api_proxy_configuration.rb +55 -3
  87. data/lib/contrast/config/application_configuration.rb +114 -15
  88. data/lib/contrast/config/assess_configuration.rb +106 -12
  89. data/lib/contrast/config/assess_rules_configuration.rb +44 -3
  90. data/lib/contrast/config/base_configuration.rb +1 -0
  91. data/lib/contrast/config/certification_configuration.rb +74 -3
  92. data/lib/contrast/config/exception_configuration.rb +61 -3
  93. data/lib/contrast/config/heap_dump_configuration.rb +101 -17
  94. data/lib/contrast/config/inventory_configuration.rb +64 -3
  95. data/lib/contrast/config/logger_configuration.rb +46 -3
  96. data/lib/contrast/config/protect_rule_configuration.rb +36 -9
  97. data/lib/contrast/config/protect_rules_configuration.rb +120 -17
  98. data/lib/contrast/config/request_audit_configuration.rb +68 -3
  99. data/lib/contrast/config/ruby_configuration.rb +96 -22
  100. data/lib/contrast/config/sampling_configuration.rb +76 -10
  101. data/lib/contrast/config/server_configuration.rb +56 -11
  102. data/lib/contrast/configuration.rb +6 -3
  103. data/lib/contrast/logger/cef_log.rb +151 -0
  104. data/lib/contrast/utils/hash_digest.rb +14 -6
  105. data/lib/contrast/utils/log_utils.rb +114 -0
  106. data/lib/contrast/utils/middleware_utils.rb +6 -7
  107. data/lib/contrast/utils/net_http_base.rb +12 -9
  108. data/lib/contrast/utils/patching/policy/patch_utils.rb +0 -4
  109. data/lib/contrast.rb +4 -3
  110. data/ruby-agent.gemspec +1 -1
  111. data/service_executables/VERSION +1 -1
  112. data/service_executables/linux/contrast-service +0 -0
  113. data/service_executables/mac/contrast-service +0 -0
  114. metadata +41 -21
  115. data/lib/contrast/agent/assess/rule/response/cachecontrol_rule.rb +0 -184
  116. data/lib/contrast/agent/assess/rule/response/clickjacking_rule.rb +0 -66
  117. data/lib/contrast/agent/assess/rule/response/x_content_type_rule.rb +0 -52
  118. data/lib/contrast/agent/assess/rule/response/x_xss_protection_rule.rb +0 -53
  119. data/lib/contrast/extension/kernel.rb +0 -54
@@ -1,28 +1,131 @@
1
1
  # Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'contrast/config/protect_rule_configuration'
5
+
4
6
  module Contrast
5
7
  module Config
6
8
  # Common Configuration settings. Those in this section pertain to the
7
9
  # protect rule modes of the Agent.
8
10
  class ProtectRulesConfiguration < BaseConfiguration
9
- KEYS = {
10
- disabled_rules: EMPTY_VALUE,
11
- 'bot-blocker' => Contrast::Config::ProtectRuleConfiguration,
12
- 'cmd-injection' => Contrast::Config::ProtectRuleConfiguration,
13
- 'sql-injection' => Contrast::Config::ProtectRuleConfiguration,
14
- 'nosql-injection' => Contrast::Config::ProtectRuleConfiguration,
15
- 'untrusted-deserialization' => Contrast::Config::ProtectRuleConfiguration,
16
- 'method-tampering' => Contrast::Config::ProtectRuleConfiguration,
17
- xxe: Contrast::Config::ProtectRuleConfiguration,
18
- 'path-traversal' => Contrast::Config::ProtectRuleConfiguration,
19
- 'reflected-xss' => Contrast::Config::ProtectRuleConfiguration,
20
- 'unsafe-file-upload' => Contrast::Config::ProtectRuleConfiguration,
21
- 'Contrast::Agent::Protect::Rule::Base' => Contrast::Config::ProtectRuleConfiguration
22
- }.cs__freeze
23
-
24
- def initialize hsh
25
- super(hsh, KEYS)
11
+ attr_reader :disabled_rules
12
+
13
+ BASE_RULE = 'Contrast::Agent::Protect::Rule::Base'.cs__freeze
14
+
15
+ def initialize hsh = {}
16
+ @disabled_rules = traverse_config(hsh, :disabled_rules)
17
+ @bot_blocker = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'bot-blocker'))
18
+ @cmd_injection = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'cmd-injection'))
19
+ @sql_injection = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'sql-injection'))
20
+ @nosql_injection = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'nosql-injection'))
21
+ @untrusted_deserialization = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(
22
+ hsh,
23
+ 'untrusted-deserialization'))
24
+ @method_tampering = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'method-tampering'))
25
+ @xxe = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, :xxe))
26
+ @path_traversal = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'path-traversal'))
27
+ @reflected_xss = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'reflected-xss'))
28
+ @unsafe_file_upload = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, 'unsafe-file-upload'))
29
+ @rule_base = Contrast::Config::ProtectRuleConfiguration.new(traverse_config(hsh, BASE_RULE))
30
+ @configuration_map = {}
31
+ build_configuration_map
32
+ end
33
+
34
+ def bot_blocker
35
+ @bot_blocker ||= Contrast::Config::ProtectRuleConfiguration.new
36
+ end
37
+
38
+ def cmd_injection
39
+ @cmd_injection ||= Contrast::Config::ProtectRuleConfiguration.new
40
+ end
41
+
42
+ def sql_injection
43
+ @sql_injection ||= Contrast::Config::ProtectRuleConfiguration.new
44
+ end
45
+
46
+ def nosql_injection
47
+ @nosql_injection ||= Contrast::Config::ProtectRuleConfiguration.new
48
+ end
49
+
50
+ def untrusted_deserialization
51
+ @untrusted_deserialization ||= Contrast::Config::ProtectRuleConfiguration.new
52
+ end
53
+
54
+ def method_tampering
55
+ @method_tampering ||= Contrast::Config::ProtectRuleConfiguration.new
56
+ end
57
+
58
+ def xxe
59
+ @xxe ||= Contrast::Config::ProtectRuleConfiguration.new
60
+ end
61
+
62
+ def path_traversal
63
+ @path_traversal ||= Contrast::Config::ProtectRuleConfiguration.new
64
+ end
65
+
66
+ def reflected_xss
67
+ @reflected_xss ||= Contrast::Config::ProtectRuleConfiguration.new
68
+ end
69
+
70
+ def unsafe_file_upload
71
+ @unsafe_file_upload ||= Contrast::Config::ProtectRuleConfiguration.new
72
+ end
73
+
74
+ def rule_base
75
+ @rule_base ||= Contrast::Config::ProtectRuleConfiguration.new
76
+ end
77
+
78
+ def [] key
79
+ send(return_proper_class(key).to_sym)
80
+ end
81
+
82
+ # Traverse the given entity to build out the configuration graph.
83
+ #
84
+ # The values will be either a hash, indicating internal nodes to
85
+ # traverse, or a value to set or the EMPTY_VALUE symbol, indicating a
86
+ # leaf node.
87
+ #
88
+ # The spec_key are the Contrast defined keys based on the instance variables of
89
+ # a given configuration.
90
+ def traverse_config values, spec_key
91
+ internal_nodes = values.cs__respond_to?(:has_key?)
92
+ val = internal_nodes ? value_from_key_config(spec_key, values) : nil
93
+ val == EMPTY_VALUE ? nil : val
94
+ end
95
+
96
+ def build_configuration_map
97
+ change_vals = { '@' => '', '-' => '_' }
98
+ regexp = Regexp.union(change_vals.keys)
99
+ instance_variables.each do |key|
100
+ str_key = key.to_s.gsub(regexp, change_vals)
101
+ next if str_key == 'configuration_map'
102
+
103
+ @configuration_map[return_proper_class(str_key)] = send(str_key.to_sym)
104
+ end
105
+ end
106
+
107
+ # This method is to handle the specific case of
108
+ # Contrast::Agent::Protect::Rule::Base from protect/base.rb#initialize
109
+ #
110
+ # @param str_key [String] the key we want to check form the config
111
+ # @return String
112
+ def return_proper_class str_key
113
+ return BASE_RULE if str_key == 'rule_base'
114
+ return 'rule_base' if str_key == BASE_RULE
115
+
116
+ str_key
117
+ end
118
+
119
+ # if method 'Contrast::Agent::Protect::Rule::Base' is being called from convert_to_hash
120
+ # handle missing method and call original getter
121
+ def method_missing name, *_args
122
+ return unless name.to_s.include?('Base') || name.to_s.start_with?('Contrast')
123
+
124
+ @rule_base
125
+ end
126
+
127
+ def respond_to_missing? method_name, include_private = false
128
+ (method_name.to_s.include?('Base') || method_name.to_s.start_with?('Contrast')) || super
26
129
  end
27
130
  end
28
131
  end
@@ -8,10 +8,75 @@ module Contrast
8
8
  class RequestAuditConfiguration < BaseConfiguration
9
9
  DEFAULT_PATH = './messages'
10
10
 
11
- KEYS = { enable: false, requests: false, responses: false, path: DEFAULT_PATH }.cs__freeze
11
+ def initialize hsh = {}
12
+ @enable = traverse_config(hsh, :enable)
13
+ @requests = traverse_config(hsh, :requests)
14
+ @responses = traverse_config(hsh, :responses)
15
+ @path = traverse_config(hsh, :path)
16
+ @configuration_map = {}
17
+ build_configuration_map
18
+ end
19
+
20
+ def enable
21
+ @enable.nil? ? false : @enable
22
+ end
23
+
24
+ def requests
25
+ @requests.nil? ? false : @requests
26
+ end
27
+
28
+ def responses
29
+ @responses.nil? ? false : @responses
30
+ end
31
+
32
+ def path
33
+ @path.nil? ? DEFAULT_PATH : @path
34
+ end
35
+
36
+ def enable= value
37
+ self['enable'] = value
38
+ end
39
+
40
+ def requests= value
41
+ self['requests'] = value
42
+ end
43
+
44
+ def responses= value
45
+ self['responses'] = value
46
+ end
47
+
48
+ def path= value
49
+ self['path'] = value
50
+ end
51
+
52
+ # TODO: RUBY-1493 MOVE TO BASE CONFIG
53
+
54
+ def []= key, value
55
+ instance_variable_set("@#{ key }".to_sym, value)
56
+ @configuration_map[key] = value
57
+ end
58
+
59
+ # Traverse the given entity to build out the configuration graph.
60
+ #
61
+ # The values will be either a hash, indicating internal nodes to
62
+ # traverse, or a value to set or the EMPTY_VALUE symbol, indicating a
63
+ # leaf node.
64
+ #
65
+ # The spec_key are the Contrast defined keys based on the instance variables of
66
+ # a given configuration.
67
+ def traverse_config values, spec_key
68
+ internal_nodes = values.cs__respond_to?(:has_key?)
69
+ val = internal_nodes ? value_from_key_config(spec_key, values) : nil
70
+ val == EMPTY_VALUE ? nil : val
71
+ end
72
+
73
+ def build_configuration_map
74
+ instance_variables.each do |key|
75
+ str_key = key.to_s.tr('@', '')
76
+ next if str_key == 'configuration_map'
12
77
 
13
- def initialize hsh
14
- super(hsh, KEYS)
78
+ @configuration_map[str_key] = send(str_key.to_sym)
79
+ end
15
80
  end
16
81
  end
17
82
  end
@@ -6,9 +6,6 @@ module Contrast
6
6
  # Common Configuration settings. Those in this section pertain to the
7
7
  # specific settings that apply to Ruby
8
8
  class RubyConfiguration < BaseConfiguration
9
- # These commands being detected will result the agent disabling instrumentation, generally any command
10
- # that doesn't result in the application listening on a port can be added here, this normally includes tasks
11
- # that are ran pre-startup(like migrations) or to show information about the application(such as routes)
12
9
  DISABLED_RAKE_TASK_LIST = %w[
13
10
  about assets:clean assets:clobber assets:environment
14
11
  assets:precompile assets:precompile:all db:create db:drop db:fixtures:load db:migrate
@@ -22,25 +19,102 @@ module Contrast
22
19
 
23
20
  DEFAULT_UNINSTRUMENTED_NAMESPACES = %w[FactoryGirl FactoryBot].cs__freeze
24
21
 
25
- KEYS = {
26
- disabled_agent_rake_tasks: DISABLED_RAKE_TASK_LIST,
27
- exceptions: Contrast::Config::ExceptionConfiguration,
28
- # controls whether or not we patch interpolation, either by rewrite or by funchook
29
- interpolate: Contrast::Utils::ObjectShare::TRUE,
30
- # controls whether or not we patch the rb_yield block to track split propagation
31
- propagate_yield: Contrast::Utils::ObjectShare::TRUE,
32
- # control whether or not we run file scanning rules on require
33
- require_scan: Contrast::Utils::ObjectShare::TRUE,
34
- # controls whether or not we track frozen Strings by replacing them
35
- track_frozen_sources: Contrast::Utils::ObjectShare::TRUE,
36
- # controls tracking outside of request
37
- non_request_tracking: Contrast::Utils::ObjectShare::FALSE,
38
- uninstrument_namespace: DEFAULT_UNINSTRUMENTED_NAMESPACES
39
-
40
- }.cs__freeze
41
-
42
- def initialize hsh
43
- super(hsh, KEYS)
22
+ attr_writer :disabled_agent_rake_tasks, :exceptions, :interpolate, :propagate_yield, :require_scan,
23
+ :track_frozen_sources, :non_request_tracking, :uninstrument_namespace
24
+
25
+ def initialize hsh = {}
26
+ @disabled_agent_rake_tasks = traverse_config(hsh, :disabled_agent_rake_tasks)
27
+ @exceptions = Contrast::Config::ExceptionConfiguration.new(traverse_config(hsh, :exceptions))
28
+ @interpolate = traverse_config(hsh, :interpolate)
29
+ @propagate_yield = traverse_config(hsh, :propagate_yield)
30
+ @require_scan = traverse_config(hsh, :require_scan)
31
+ @track_frozen_sources = traverse_config(hsh, :track_frozen_sources)
32
+ @non_request_tracking = traverse_config(hsh, :non_request_tracking)
33
+ @uninstrument_namespace = traverse_config(hsh, :uninstrument_namespace)
34
+ @configuration_map = {}
35
+ build_configuration_map
36
+ end
37
+
38
+ # These commands being detected will result the agent disabling instrumentation, generally any command
39
+ # that doesn't result in the application listening on a port can be added here, this normally includes tasks
40
+ # that are ran pre-startup(like migrations) or to show information about the application(such as routes)
41
+ # @return [Array, DISABLED_RAKE_TASK_LIST]
42
+ def disabled_agent_rake_tasks
43
+ @disabled_agent_rake_tasks.nil? ? DISABLED_RAKE_TASK_LIST : @disabled_agent_rake_tasks
44
+ end
45
+
46
+ # @return [Contrast::Config::ExceptionConfiguration]
47
+ def exceptions
48
+ @exceptions ||= Contrast::Config::ExceptionConfiguration.new
49
+ end
50
+
51
+ # controls whether or not we patch interpolation, either by rewrite or by funchook
52
+ # @return [Boolean, Contrast::Utils::ObjectShare::TRUE]
53
+ def interpolate
54
+ @interpolate.nil? ? Contrast::Utils::ObjectShare::TRUE : @interpolate
55
+ end
56
+
57
+ # controls whether or not we patch the rb_yield block to track split propagation
58
+ # @return [Boolean, Contrast::Utils::ObjectShare::TRUE]
59
+ def propagate_yield
60
+ @propagate_yield.nil? ? Contrast::Utils::ObjectShare::TRUE : @propagate_yield
61
+ end
62
+
63
+ # control whether or not we run file scanning rules on require
64
+ # @return [Boolean, Contrast::Utils::ObjectShare::TRUE]
65
+ def require_scan
66
+ @require_scan.nil? ? Contrast::Utils::ObjectShare::TRUE : @require_scan
67
+ end
68
+
69
+ # controls whether or not we track frozen Strings by replacing them
70
+ # @return [Boolean, Contrast::Utils::ObjectShare::TRUE]
71
+ def track_frozen_sources
72
+ @track_frozen_sources.nil? ? Contrast::Utils::ObjectShare::TRUE : @track_frozen_sources
73
+ end
74
+
75
+ # controls tracking outside of request
76
+ # @return [Boolean, Contrast::Utils::ObjectShare::FALSE]
77
+ def non_request_tracking
78
+ @non_request_tracking.nil? ? Contrast::Utils::ObjectShare::FALSE : @non_request_tracking
79
+ end
80
+
81
+ # @return [Array, DEFAULT_UNINSTRUMENTED_NAMESPACES]
82
+ def uninstrument_namespace
83
+ @uninstrument_namespace.nil? ? DEFAULT_UNINSTRUMENTED_NAMESPACES : @uninstrument_namespace
84
+ end
85
+
86
+ # TODO: RUBY-1493 MOVE TO BASE CONFIG
87
+
88
+ def []= key, value
89
+ instance_variable_set("@#{ key }".to_sym, value)
90
+ @configuration_map[key] = value
91
+ end
92
+
93
+ def [] key
94
+ send(key.to_sym)
95
+ end
96
+
97
+ # Traverse the given entity to build out the configuration graph.
98
+ #
99
+ # The values will be either a hash, indicating internal nodes to
100
+ # traverse, or a value to set or the EMPTY_VALUE symbol, indicating a
101
+ # leaf node.
102
+ #
103
+ # The spec_key are the Contrast defined keys based on the instance variables of
104
+ # a given configuration.
105
+ def traverse_config values, spec_key
106
+ internal_nodes = values.cs__respond_to?(:has_key?)
107
+ val = internal_nodes ? value_from_key_config(spec_key, values) : nil
108
+ val == EMPTY_VALUE ? nil : val
109
+ end
110
+
111
+ def build_configuration_map
112
+ instance_variables.each do |key|
113
+ str_key = key.to_s.tr('@', '')
114
+ next if str_key == 'configuration_map'
115
+
116
+ @configuration_map[str_key] = send(str_key.to_sym)
117
+ end
44
118
  end
45
119
  end
46
120
  end
@@ -6,16 +6,82 @@ module Contrast
6
6
  # Common Configuration settings. Those in this section pertain to the
7
7
  # sampling functionality of the Agent.
8
8
  class SamplingConfiguration < BaseConfiguration
9
- KEYS = {
10
- enable: EMPTY_VALUE,
11
- baseline: EMPTY_VALUE,
12
- request_frequency: EMPTY_VALUE,
13
- response_frequency: EMPTY_VALUE,
14
- window_ms: EMPTY_VALUE
15
- }.cs__freeze
16
-
17
- def initialize hsh
18
- super(hsh, KEYS)
9
+ # @return [Integer, nil]
10
+ attr_reader :baseline
11
+ # @return [Integer, nil]
12
+ attr_reader :request_frequency
13
+ # @return [Integer, nil]
14
+ attr_reader :response_frequency
15
+ # @return [Integer, nil]
16
+ attr_reader :window_ms
17
+
18
+ def initialize hsh = {}
19
+ @enable = traverse_config(hsh, :enable)
20
+ @baseline = traverse_config(hsh, :baseline)
21
+ @request_frequency = traverse_config(hsh, :request_frequency)
22
+ @response_frequency = traverse_config(hsh, :response_frequency)
23
+ @window_ms = traverse_config(hsh, :window_ms)
24
+ @configuration_map = {}
25
+ build_configuration_map
26
+ end
27
+
28
+ # @return [Boolean, false]
29
+ def enable
30
+ @enable.nil? ? false : @enable
31
+ end
32
+
33
+ def enable= value
34
+ self['enable'] = value
35
+ end
36
+
37
+ def baseline= value
38
+ self['baseline'] = value
39
+ end
40
+
41
+ def request_frequency= value
42
+ self['request_frequency'] = value
43
+ end
44
+
45
+ def response_frequency= value
46
+ self['response_frequency'] = value
47
+ end
48
+
49
+ def window_ms= value
50
+ self['window_ms'] = value
51
+ end
52
+
53
+ # TODO: RUBY-1493 MOVE TO BASE CONFIG
54
+
55
+ def []= key, value
56
+ instance_variable_set("@#{ key }".to_sym, value)
57
+ @configuration_map[key] = value
58
+ end
59
+
60
+ def [] key
61
+ send(key.to_sym)
62
+ end
63
+
64
+ # Traverse the given entity to build out the configuration graph.
65
+ #
66
+ # The values will be either a hash, indicating internal nodes to
67
+ # traverse, or a value to set or the EMPTY_VALUE symbol, indicating a
68
+ # leaf node.
69
+ #
70
+ # The spec_key are the Contrast defined keys based on the instance variables of
71
+ # a given configuration.
72
+ def traverse_config values, spec_key
73
+ internal_nodes = values.cs__respond_to?(:has_key?)
74
+ val = internal_nodes ? value_from_key_config(spec_key, values) : nil
75
+ val == EMPTY_VALUE ? nil : val
76
+ end
77
+
78
+ def build_configuration_map
79
+ instance_variables.each do |key|
80
+ str_key = key.to_s.tr('@', '')
81
+ next if str_key == 'configuration_map'
82
+
83
+ @configuration_map[str_key] = send(str_key.to_sym)
84
+ end
19
85
  end
20
86
  end
21
87
  end
@@ -6,17 +6,62 @@ module Contrast
6
6
  # Common Configuration settings. Those in this section pertain to the
7
7
  # server identification functionality of the Agent.
8
8
  class ServerConfiguration < BaseConfiguration
9
- KEYS = {
10
- name: EMPTY_VALUE,
11
- path: EMPTY_VALUE,
12
- type: EMPTY_VALUE,
13
- tags: EMPTY_VALUE,
14
- environment: EMPTY_VALUE,
15
- version: EMPTY_VALUE
16
- }.cs__freeze
17
-
18
- def initialize hsh
19
- super(hsh, KEYS)
9
+ # @return [String, nil]
10
+ attr_accessor :name
11
+ # @return [String, nil]
12
+ attr_accessor :path
13
+ # @return [String, nil]
14
+ attr_accessor :type
15
+ # @return [Array, nil]
16
+ attr_accessor :tags
17
+ # @return [String, nil]
18
+ attr_accessor :environment
19
+ # @return [String, nil]
20
+ attr_accessor :version
21
+
22
+ def initialize hsh = {}
23
+ @path = traverse_config(hsh, :path)
24
+ @name = traverse_config(hsh, :name)
25
+ @type = traverse_config(hsh, :type)
26
+ @tags = traverse_config(hsh, :tags)
27
+ @environment = traverse_config(hsh, :environment)
28
+ @version = traverse_config(hsh, :version)
29
+ @configuration_map = {}
30
+ build_configuration_map
31
+ end
32
+
33
+ # TODO: RUBY-1493 MOVE TO BASE CONFIG
34
+
35
+ def []= key, value
36
+ instance_variable_set("@#{ key }".to_sym, value)
37
+ @configuration_map[key] = value
38
+ end
39
+
40
+ def [] key
41
+ send(key.to_sym)
42
+ end
43
+
44
+ # Traverse the given entity to build out the configuration graph.
45
+ #
46
+ # The values will be either a hash, indicating internal nodes to
47
+ # traverse, or a value to set or the EMPTY_VALUE symbol, indicating a
48
+ # leaf node.
49
+ #
50
+ # The spec_key are the Contrast defined keys based on the instance variables of
51
+ # a given configuration.
52
+ def traverse_config values, spec_key
53
+ internal_nodes = values.cs__respond_to?(:has_key?)
54
+ val = internal_nodes ? value_from_key_config(spec_key, values) : nil
55
+ val == EMPTY_VALUE ? nil : val
56
+ end
57
+
58
+ def build_configuration_map
59
+ instance_variables.each do |key|
60
+ str_key = key.to_s.tr('@', '')
61
+ next if str_key == 'configuration_map'
62
+
63
+ @configuration_map[str_key] = send(str_key.to_sym)
64
+ end
20
65
  end
21
66
  end
22
67
  end
@@ -217,10 +217,13 @@ module Contrast
217
217
  def convert_to_hash convert = root, hash = {}
218
218
  case convert
219
219
  when Contrast::Config::BaseConfiguration
220
- convert.cs__class::KEYS.each_key do |key|
221
- next if Contrast::Utils::ExcludeKey.excludable? key.to_s
220
+ # to_hash returns @configuration_map
221
+ convert.to_hash.each_key do |key|
222
+ next if Contrast::Utils::ExcludeKey.excludable?(key.to_s)
222
223
 
223
- hash[key] = convert_to_hash(convert.send(key), {})
224
+ # keys can contain '-' but methods getters cannot
225
+ # clean_key = key.to_s.tr('-', '_')
226
+ hash[key] = convert_to_hash(convert.send(key.to_sym), {})
224
227
  end
225
228
  hash
226
229
  else