contrast-agent 7.0.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/contrast/agent/assess/policy/policy.rb +1 -1
  3. data/lib/contrast/agent/deadzone/policy/policy.rb +1 -1
  4. data/lib/contrast/agent/patching/policy/policy.rb +2 -2
  5. data/lib/contrast/agent/protect/input_analyzer/worth_watching_analyzer.rb +3 -0
  6. data/lib/contrast/agent/protect/rule/no_sqli/no_sqli.rb +1 -1
  7. data/lib/contrast/agent/reporting/reporter.rb +19 -4
  8. data/lib/contrast/agent/reporting/reporting_events/agent_effective_config.rb +32 -0
  9. data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +7 -0
  10. data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +3 -1
  11. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +11 -7
  12. data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +15 -7
  13. data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +2 -1
  14. data/lib/contrast/agent/reporting/reporting_workers/application_server_worker.rb +3 -0
  15. data/lib/contrast/agent/reporting/reporting_workers/reporter_heartbeat.rb +3 -0
  16. data/lib/contrast/agent/reporting/reporting_workers/server_settings_worker.rb +3 -0
  17. data/lib/contrast/agent/telemetry/base.rb +37 -12
  18. data/lib/contrast/agent/telemetry/client.rb +1 -3
  19. data/lib/contrast/agent/telemetry/telemetry.rb +0 -7
  20. data/lib/contrast/agent/thread/thread_watcher.rb +2 -2
  21. data/lib/contrast/agent/version.rb +1 -1
  22. data/lib/contrast/components/agent.rb +1 -1
  23. data/lib/contrast/components/api.rb +2 -2
  24. data/lib/contrast/components/app_context.rb +1 -1
  25. data/lib/contrast/components/assess.rb +1 -1
  26. data/lib/contrast/components/assess_rules.rb +1 -1
  27. data/lib/contrast/components/base.rb +3 -3
  28. data/lib/contrast/components/config/sources.rb +12 -9
  29. data/lib/contrast/components/config.rb +2 -2
  30. data/lib/contrast/components/protect.rb +2 -2
  31. data/lib/contrast/components/sampling.rb +6 -4
  32. data/lib/contrast/components/settings.rb +1 -1
  33. data/lib/contrast/config/certification_configuration.rb +1 -1
  34. data/lib/contrast/config/configuration_files.rb +47 -0
  35. data/lib/contrast/config/diagnostics/command_line.rb +24 -0
  36. data/lib/contrast/config/{config.rb → diagnostics/config.rb} +21 -6
  37. data/lib/contrast/config/diagnostics/contrast_ui.rb +24 -0
  38. data/lib/contrast/config/diagnostics/effective_config.rb +28 -0
  39. data/lib/contrast/config/diagnostics/effective_config_value.rb +14 -0
  40. data/lib/contrast/config/diagnostics/environment_variables.rb +51 -0
  41. data/lib/contrast/config/{diagnostics.rb → diagnostics/monitor.rb} +10 -10
  42. data/lib/contrast/config/diagnostics/source_config_value.rb +51 -0
  43. data/lib/contrast/config/diagnostics/tools.rb +188 -0
  44. data/lib/contrast/config/diagnostics/user_configuration_file.rb +44 -0
  45. data/lib/contrast/config/request_audit_configuration.rb +1 -1
  46. data/lib/contrast/config/server_configuration.rb +1 -1
  47. data/lib/contrast/configuration.rb +90 -57
  48. data/lib/contrast/utils/hash_utils.rb +43 -0
  49. data/lib/contrast/utils/json.rb +46 -0
  50. data/lib/contrast/utils/net_http_base.rb +75 -26
  51. metadata +16 -7
  52. data/lib/contrast/config/diagnostics_tools.rb +0 -99
  53. data/lib/contrast/config/effective_config.rb +0 -131
  54. data/lib/contrast/config/effective_config_value.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc98145df7f08bc47cbff0f0416a7b43852b8075c6806bd38fbbe0aa27d94adb
4
- data.tar.gz: 60885ba415f59b893a5da6101ddc3b9d6deeac5a9d41bb2eb7c459291873b08f
3
+ metadata.gz: 81222798666699f86b31b925d531d2ee2229eb7934582d2a502cc61de3ca4e0b
4
+ data.tar.gz: 7dd4d41a58600b7d57b5f57cf95c42bd2f6d198f5f1906e93751e33c09efa3e0
5
5
  SHA512:
6
- metadata.gz: 4a6449786512d444818087fed5d880c061b1108b8e9fbe64e4fd0f3657bac3b53ffb60806a7767a50a9c7a910b5e62e223d6af84be51d8ca9b6e4e5b5ae67d07
7
- data.tar.gz: 4f2cb9c1435fbe5fdfbccbc3cc69ba3823de97f617bcff63493087a70a0551852dbe09f7699089cd22dfc509e57c39525420290813cd12ac92ee91164e2910bc
6
+ metadata.gz: 02e5d3aa6b342e8c4277ad6cefde65819aed6f6b4a1079cfe7528fcce236ec702aa8a63fc756c403c0df6e3ef38d5d25dc9f1c6e5c450d272122d699b6fd9872
7
+ data.tar.gz: 9cc83b5f69edeea949784ae766be7e02c1d589e58b2af5b5c1bd7975dcee1450d294bc7de647f60a9a3f18a1ea05a43bfe452a52d4760ed1b1cfcb0a7339a6ab
@@ -58,7 +58,7 @@ module Contrast
58
58
  # can skip policy loading.
59
59
  return if disabled_globally?
60
60
 
61
- policy_data = JSON.parse(string)
61
+ policy_data = Contrast::Utils::Json.parse(string)
62
62
 
63
63
  policy_data[SOURCES_KEY].each do |source_hash|
64
64
  source = Contrast::Agent::Assess::Policy::SourceNode.new(source_hash)
@@ -28,7 +28,7 @@ module Contrast
28
28
  end
29
29
 
30
30
  def from_hash_string string
31
- policy_data = JSON.parse(string)
31
+ policy_data = Contrast::Utils::Json.parse(string)
32
32
 
33
33
  policy_data[DEADZONES_KEY].each do |deadzone_hash|
34
34
  add_node(node_type.new(deadzone_hash))
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'json'
4
+ require 'contrast/utils/json'
5
5
  require 'singleton'
6
6
 
7
7
  require 'contrast'
@@ -71,7 +71,7 @@ module Contrast
71
71
  # it, so in that case, we can skip policy loading.
72
72
  return if disabled_globally?
73
73
 
74
- policy_data = JSON.parse(string)
74
+ policy_data = Contrast::Utils::Json.parse(string)
75
75
 
76
76
  policy_data[RULES_KEY].each do |rule_hash|
77
77
  rule_hash[TRIGGERS_KEY].each do |trigger_hash|
@@ -26,11 +26,14 @@ module Contrast
26
26
  # Thread that will process all the InputAnalysisResults that have a score level of WORTHWATCHING and
27
27
  # sends results to TeamServer
28
28
  def start_thread!
29
+ return unless attempt_to_start?
29
30
  return if running?
30
31
 
31
32
  @_thread = Contrast::Agent::Thread.new do
32
33
  logger.info('[WorthWatchingAnalyzer] Starting thread.')
33
34
  loop do
35
+ break unless attempt_to_start?
36
+
34
37
  sleep(REPORT_INTERVAL_SECOND)
35
38
  next if queue.empty?
36
39
 
@@ -94,7 +94,7 @@ module Contrast
94
94
  #
95
95
  # @return [Boolean]
96
96
  def json? string
97
- return true if JSON.parse(string)
97
+ return true if Contrast::Utils::Json.parse(string)
98
98
  rescue StandardError
99
99
  false
100
100
  end
@@ -10,10 +10,12 @@ require 'contrast/agent/telemetry/exception'
10
10
  module Contrast
11
11
  module Agent
12
12
  # This module will hold everything essential to reporting to TeamServer
13
- class Reporter < WorkerThread
13
+ class Reporter < WorkerThread # rubocop:disable Metrics/ClassLength
14
14
  include Contrast::Components::Logger::InstanceMethods
15
15
  include Contrast::Utils::ObjectShare
16
16
 
17
+ # How many tries to reconnect the Reporter should make.
18
+ RETRY_ATTEMPTS = 10
17
19
  MAX_QUEUE_SIZE = 1000
18
20
 
19
21
  class << self
@@ -35,13 +37,17 @@ module Contrast
35
37
  end
36
38
 
37
39
  def start_thread!
40
+ return unless attempt_to_start?
38
41
  return if running?
39
42
 
43
+ @connection_attempts = 0
44
+
40
45
  client.startup!(connection)
41
46
  @_thread = Contrast::Agent::Thread.new do
42
47
  logger.debug('[Reporter] Starting background Reporter thread.')
43
48
  loop do
44
49
  next unless connected?
50
+ break unless attempt_to_start?
45
51
 
46
52
  process_event(queue.pop)
47
53
  rescue StandardError => e
@@ -124,10 +130,19 @@ module Contrast
124
130
  #
125
131
  # @return [Boolean]
126
132
  def connected?
127
- return true if client && connection
133
+ if client && connection
134
+ # Try to resend startup messages now with connection:
135
+ client.startup!(connection) unless client.status.startup_messages_sent?
136
+ return true
137
+ end
128
138
 
129
- logger.debug('[Reporter] No client/connection; sleeping...', client: client, connection: connection)
130
- sleep(5)
139
+ logger.debug('[Reporter] No client/connection; sleeping...')
140
+ @connection_attempts += 1
141
+ if @connection_attempts >= RETRY_ATTEMPTS
142
+ logger.debug('[Reporter] shutting down..')
143
+ Contrast::AGENT.disable!
144
+ end
145
+ sleep(5) unless Contrast::AGENT.disabled?
131
146
  false
132
147
  end
133
148
 
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
+ # frozen_string_literal: true
3
+
4
+ require 'contrast/agent/reporting/reporting_events/reporting_event'
5
+ require 'contrast/config'
6
+
7
+ module Contrast
8
+ module Agent
9
+ module Reporting
10
+ # AgentStartup Event which sends the agent data to TeamServer on the startup of a server or process,
11
+ # used to create a new Server entity there.
12
+ class AgentEffectiveConfig < Contrast::Agent::Reporting::ReportingEvent
13
+ # @param diagnostics [Contrast::Agent::DiagnosticsConfig::Diagnostics] current diagnostics
14
+ def initialize diagnostics
15
+ @event_method = :PUT
16
+ @event_endpoint = Contrast::Agent::Reporting::Endpoints.effective_config
17
+ @event_type = :effective_config
18
+ @diagnostics = diagnostics
19
+ super()
20
+ end
21
+
22
+ def file_name
23
+ 'agent-effective-config'
24
+ end
25
+
26
+ def to_controlled_hash
27
+ @diagnostics.to_controlled_hash
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -83,6 +83,13 @@ module Contrast
83
83
  end
84
84
  end
85
85
 
86
+ # @return [String, nil]
87
+ def effective_config
88
+ with_rescue do
89
+ "#{ application_endpoint }/effective-config".cs__freeze
90
+ end
91
+ end
92
+
86
93
  private
87
94
 
88
95
  # Returns the URL needed to connect to endpoints in TeamServer required for application related information.
@@ -11,7 +11,7 @@ module Contrast
11
11
  # This class will build the required headers for agent reporting to TS
12
12
  class Headers
13
13
  attr_reader :app_name, :api_key, :agent_version, :app_language, :app_path, :app_version, :authorization,
14
- :server_name, :server_path, :server_type, :content_type, :encoding, :compression
14
+ :server_name, :server_path, :server_type, :content_type, :encoding, :compression, :session_id
15
15
 
16
16
  include Contrast::Utils::ObjectShare
17
17
  ENCODING = 'base64'
@@ -29,6 +29,7 @@ module Contrast
29
29
  @server_name = Base64.strict_encode64(Contrast::APP_CONTEXT.server_name)
30
30
  @server_path = Base64.strict_encode64(Contrast::APP_CONTEXT.server_path)
31
31
  @server_type = Base64.strict_encode64(Contrast::APP_CONTEXT.server_type)
32
+ @session_id = Contrast::CONFIG.session_id
32
33
  @content_type = CONTENT_TYPE
33
34
  @encoding = ENCODING
34
35
  @compression = COMPRESSION
@@ -46,6 +47,7 @@ module Contrast
46
47
  server_name: @server_name,
47
48
  server_path: @server_path,
48
49
  server_type: @server_type,
50
+ 'Session-ID': @session_id,
49
51
  content_type: @content_type,
50
52
  encoding: @encoding,
51
53
  compression: @compression
@@ -5,14 +5,15 @@ require 'json'
5
5
  require 'net/http'
6
6
  require 'contrast/components/logger'
7
7
  require 'contrast/utils/net_http_base'
8
+ require 'contrast/config/diagnostics/monitor'
8
9
  require 'contrast/agent/reporting/connection_status'
9
- require 'contrast/agent/reporting/reporting_utilities/response_handler'
10
- require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
11
- require 'contrast/agent/reporting/reporting_utilities/endpoints'
12
10
  require 'contrast/agent/reporting/reporting_utilities/headers'
11
+ require 'contrast/agent/reporting/reporting_utilities/endpoints'
13
12
  require 'contrast/agent/reporting/reporting_events/server_settings'
13
+ require 'contrast/agent/reporting/reporting_utilities/response_handler'
14
14
  require 'contrast/agent/reporting/reporting_events/application_settings'
15
- require 'contrast/config/diagnostics'
15
+ require 'contrast/agent/reporting/reporting_events/agent_effective_config'
16
+ require 'contrast/agent/reporting/reporting_utilities/reporter_client_utils'
16
17
 
17
18
  module Contrast
18
19
  module Agent
@@ -57,6 +58,7 @@ module Contrast
57
58
  # @param connection [Net::HTTP] open connection
58
59
  def startup! connection
59
60
  return if status.startup_messages_sent?
61
+ return unless connection
60
62
 
61
63
  send_agent_startup(connection)
62
64
  end
@@ -76,7 +78,7 @@ module Contrast
76
78
  response = connection.request(request)
77
79
  audit&.audit_event(event, response) if ::Contrast::API.request_audit_enable
78
80
  process_settings_response(response, event)
79
- record_configuration(response, event)
81
+ report_configuration(response, event)
80
82
  process_preflight_response(event, response, connection)
81
83
  response
82
84
  rescue StandardError => e
@@ -90,7 +92,7 @@ module Contrast
90
92
  #
91
93
  # @param response [Contrast::Agent::Reporting::Response, nil]
92
94
  # @param event [Contrast::Agent::Reporting::ReportingEvent]
93
- def record_configuration response, event
95
+ def report_configuration response, event
94
96
  return unless response
95
97
 
96
98
  diagnostics.config.determine_config_status(response_handler.last_response_code || response.code)
@@ -99,6 +101,8 @@ module Contrast
99
101
 
100
102
  logger.info('[Reporter Diagnostics] last response code:', response_code: response_handler.last_response_code)
101
103
  diagnostics.write_to_file
104
+ config_event = Contrast::Agent::Reporting::AgentEffectiveConfig.new(diagnostics)
105
+ Contrast::Agent.reporter.send_event(config_event)
102
106
  end
103
107
 
104
108
  def status
@@ -110,7 +114,7 @@ module Contrast
110
114
  end
111
115
 
112
116
  def diagnostics
113
- @_diagnostics ||= Contrast::Agent::DiagnosticsConfig::Diagnostics.new(Contrast::LOGGER.path)
117
+ @_diagnostics ||= Contrast::Config::Diagnostics::Monitor.new(Contrast::LOGGER.path)
114
118
  end
115
119
 
116
120
  def sleep?
@@ -53,19 +53,15 @@ module Contrast
53
53
  # @param request [Net::HTTPRequest]
54
54
  # @return [Net::HTTPRequest]
55
55
  def build_headers request
56
- app_version = @headers.app_version
57
- request['API-Key'] = @headers.api_key
58
- request['Application-Language'] = @headers.app_language
59
- request['Application-Name'] = @headers.app_name
60
- request['Application-Path'] = @headers.app_path
61
- request['Application-Version'] = app_version if app_version
56
+ build_application_headers(request)
57
+ build_encode_and_compress_headers(request)
62
58
  request['Authorization'] = @headers.authorization
63
59
  request['Server-Name'] = @headers.server_name
64
60
  request['Server-Path'] = @headers.server_path
65
61
  request['Server-Type'] = @headers.server_type
66
62
  request['X-Contrast-Agent'] = @headers.agent_version
67
63
  request['X-Contrast-Header-Encoding'] = @headers.encoding
68
- build_encode_and_compress_headers(request)
64
+ request['Session-ID'] = @headers.session_id
69
65
  request
70
66
  end
71
67
 
@@ -155,6 +151,18 @@ module Contrast
155
151
  request['X-Contrast-Encoding'] = @headers.compression
156
152
  request['Content-Encoding'] = @headers.compression
157
153
  end
154
+
155
+ # Adds corresponding application headers to request.
156
+ #
157
+ # @param request [Net::HTTPRequest]
158
+ def build_application_headers request
159
+ app_version = @headers.app_version
160
+ request['API-Key'] = @headers.api_key
161
+ request['Application-Language'] = @headers.app_language
162
+ request['Application-Name'] = @headers.app_name
163
+ request['Application-Path'] = @headers.app_path
164
+ request['Application-Version'] = app_version if app_version
165
+ end
158
166
  end
159
167
  end
160
168
  end
@@ -4,6 +4,7 @@
4
4
  require 'contrast/agent/reporting/reporting_utilities/ng_response_extractor'
5
5
  require 'contrast/agent/reporting/reporting_utilities/response_extractor'
6
6
  require 'contrast/agent/reactions/disable_reaction'
7
+ require 'contrast/utils/json'
7
8
 
8
9
  module Contrast
9
10
  module Agent
@@ -257,7 +258,7 @@ module Contrast
257
258
  response_body = response&.body
258
259
  return unless response_body
259
260
 
260
- response_data = JSON.parse(response_body, symbolize_names: true)
261
+ response_data = Contrast::Utils::Json.parse(response_body, deep_symbolize: true)
261
262
  return unless response_data.cs__is_a?(Hash)
262
263
 
263
264
  extract_response_last_modified(response, event)
@@ -13,11 +13,14 @@ module Contrast
13
13
  RESEND_INTERVAL_MS = 30_000.cs__freeze
14
14
 
15
15
  def start_thread!
16
+ return unless attempt_to_start?
16
17
  return if running?
17
18
 
18
19
  @_thread = Contrast::Agent::Thread.new do
19
20
  logger.info('[ApplicationSettingsWorker] Starting thread.', sending_interval: application_server_ms)
20
21
  loop do
22
+ break unless attempt_to_start?
23
+
21
24
  logger.info('[ApplicationSettingsWorker] Fetching Settings', sending_interval: application_server_ms)
22
25
  Contrast::Agent.reporter&.send_event(application_settings_message)
23
26
  sleep(application_server_ms / 1000)
@@ -19,11 +19,14 @@ module Contrast
19
19
  REFRESH_INTERVAL_SEC = 60
20
20
 
21
21
  def start_thread!
22
+ return unless attempt_to_start?
22
23
  return if running?
23
24
 
24
25
  @_thread = Contrast::Agent::Thread.new do
25
26
  logger.info('[Heartbeat] Starting thread.')
26
27
  loop do
28
+ break unless attempt_to_start?
29
+
27
30
  polling_events.each do |event|
28
31
  Contrast::Agent.reporter&.send_event(event)
29
32
  end
@@ -13,11 +13,14 @@ module Contrast
13
13
  RESEND_INTERVAL_MS = 60_000.cs__freeze
14
14
 
15
15
  def start_thread!
16
+ return unless attempt_to_start?
16
17
  return if running?
17
18
 
18
19
  @_thread = Contrast::Agent::Thread.new do
19
20
  logger.info('[ServerSettingsWorker] Starting thread.', sending_interval: server_settings_resend_ms)
20
21
  loop do
22
+ break unless attempt_to_start?
23
+
21
24
  logger.info('[ServerSettingsWorker] Fetching Settings', sending_interval: server_settings_resend_ms)
22
25
  Contrast::Agent.reporter&.send_event(settings_message)
23
26
  sleep(server_settings_resend_ms / 1000)
@@ -46,6 +46,39 @@ module Contrast
46
46
  @enabled
47
47
  end
48
48
 
49
+ # In case of connection error, do not create the background thread or queue,
50
+ # as if the opt-out env var was set.
51
+ #
52
+ # @return [Boolean]
53
+ def ip_opt_out?
54
+ @_ip_opt_out ||= begin
55
+ test_conn = Contrast::Agent::Telemetry::Client.new.initialize_connection(URL)
56
+
57
+ if test_conn.nil? || Contrast::Utils::NetHttpBase.last_error
58
+ # log if error:
59
+ if defined?(Contrast) && defined?(Contrast::CONFIG) && defined?(Contrast::CONFIG)
60
+ Contrast::CONFIG.proto_logger.warn('[Telemetry] connection error disabling...',
61
+ error: Contrast::Utils::NetHttpBase.last_error)
62
+
63
+ end
64
+ # Disable telemetry:
65
+ @enabled = false
66
+ true
67
+ else
68
+ # Close the connection
69
+ test_conn.finish if test_conn.started?
70
+ false
71
+ end
72
+ end
73
+ rescue StandardError
74
+ @enabled = false
75
+ true
76
+ end
77
+
78
+ def disable!
79
+ @enabled = false
80
+ end
81
+
49
82
  private
50
83
 
51
84
  def telemetry_enabled?
@@ -56,15 +89,7 @@ module Contrast
56
89
 
57
90
  # In case of connection error, do not create the background thread or queue,
58
91
  # as if the opt-out env var was set
59
- @_client = Contrast::Agent::Telemetry::Client.new
60
- ip_opt_out_telemetry = @_client.initialize_connection(URL)
61
- if ip_opt_out_telemetry.nil?
62
- # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
63
- # an infinite loop w/ telemetry
64
- logger.debug("[Telemetry] Connection was not established properly!!! \n
65
- Telemetry reporting will be disabled!")
66
- return false
67
- end
92
+ return false if ip_opt_out?
68
93
 
69
94
  true
70
95
  end
@@ -91,6 +116,7 @@ module Contrast
91
116
  end
92
117
 
93
118
  def start_thread!
119
+ return unless attempt_to_start?
94
120
  return if running?
95
121
 
96
122
  logger.debug('[Telemetry] Starting background telemetry thread.')
@@ -140,6 +166,7 @@ module Contrast
140
166
  Contrast::Agent::Thread.new do
141
167
  loop do
142
168
  next unless client && connection
169
+ break unless attempt_to_start?
143
170
 
144
171
  # Start pushing exceptions to queue for reporting.
145
172
  Contrast::TELEMETRY_EXCEPTIONS.each_value { |value| queue << value }
@@ -155,9 +182,7 @@ module Contrast
155
182
  sleep(retry_sleep_time) unless retry_sleep_time.nil?
156
183
  end
157
184
  rescue StandardError => e
158
- # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
159
- # an infinite loop w/ telemetry
160
- logger.debug('[Telemetry] Could not send message to service from telemetry queue.', e)
185
+ logger.error('[Telemetry] Could not send message to service from telemetry queue.', e)
161
186
  stop!
162
187
  end
163
188
  end
@@ -100,9 +100,7 @@ module Contrast
100
100
  def get_event_json event
101
101
  Array(event.to_controlled_hash).to_json
102
102
  rescue Exception => e # rubocop:disable Lint/RescueException
103
- # TODO: RUBY-2033 we cannot log the error above debug level here b/c it results in
104
- # an infinite loop w/ telemetry
105
- logger.debug('[Telemetry] Unable to convert TelemetryEvent to JSON string', e, hsh)
103
+ logger.error('[Telemetry] Unable to convert TelemetryEvent to JSON string', e, hsh)
106
104
  raise(e)
107
105
  end
108
106
  end
@@ -92,13 +92,6 @@ module Contrast
92
92
  #
93
93
  # @return [Boolean]
94
94
  def telemetry_exceptions_enabled?
95
- opts_out_telemetry = return_value(:telemetry_opt_outs).to_s
96
- return false if opts_out_telemetry.casecmp?('true') || opts_out_telemetry == '1'
97
- # Double check if telemetry is enabled, this includes a check for Agent enable setting in the
98
- # config. In case of disabled Agent the queue won't be created and the Telemetry would not
99
- # be enabled. This check is here to prevent a loop of error creations that could no be added
100
- # to a queue ( because the client cannot be initialized if the Agent is disabled or settings are
101
- # missing).
102
95
  return false unless Contrast::Agent::Telemetry::Base.enabled?
103
96
 
104
97
  true
@@ -6,7 +6,7 @@ require 'contrast/agent/reporting/report'
6
6
  require 'contrast/agent/reporting/reporting_workers/reporting_workers'
7
7
  require 'contrast/agent/telemetry/base'
8
8
  require 'contrast/agent/protect/input_analyzer/worth_watching_analyzer'
9
- require 'contrast/config/diagnostics'
9
+ require 'contrast/config/diagnostics/monitor'
10
10
  require 'contrast/utils/job_servers_running'
11
11
 
12
12
  module Contrast
@@ -114,7 +114,7 @@ module Contrast
114
114
  def check_before_start
115
115
  return if Contrast::CONFIG.send(:validate)
116
116
 
117
- @_diagnostics = Contrast::Agent::DiagnosticsConfig::Diagnostics.new(Contrast::AGENT.logger.path ||
117
+ @_diagnostics = Contrast::Config::Diagnostics::Monitor.new(Contrast::AGENT.logger.path ||
118
118
  Contrast::Components::Config::CONTRAST_LOG)
119
119
  @_diagnostics.config.populate_fail_connection
120
120
  @_diagnostics.write_to_file_logic(false, reset: false)
@@ -3,6 +3,6 @@
3
3
 
4
4
  module Contrast
5
5
  module Agent
6
- VERSION = '7.0.0'
6
+ VERSION = '7.1.0'
7
7
  end
8
8
  end
@@ -137,7 +137,7 @@ module Contrast
137
137
  # Converts current configuration to effective config values class and appends them to
138
138
  # EffectiveConfig class.
139
139
  #
140
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
140
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
141
141
  def to_effective_config effective_config
142
142
  super
143
143
  logger&.to_effective_config(effective_config)
@@ -127,7 +127,7 @@ module Contrast
127
127
  # Converts current configuration to effective config values class and appends them to
128
128
  # EffectiveConfig class.
129
129
  #
130
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
130
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
131
131
  def to_effective_config effective_config
132
132
  add_effective_config_values(effective_config, CONFIG_VALUES, CANON_NAME, CONTRAST)
133
133
  effective_proxy(effective_config)
@@ -137,7 +137,7 @@ module Contrast
137
137
 
138
138
  private
139
139
 
140
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
140
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
141
141
  def effective_proxy effective_config
142
142
  add_single_effective_value(effective_config, ENABLE, proxy_enable.to_s, PROXY_NAME, "#{ CONTRAST }.proxy")
143
143
  return unless proxy_url && proxy_enable
@@ -161,7 +161,7 @@ module Contrast
161
161
  # Converts current configuration to effective config values class and appends them to
162
162
  # EffectiveConfig class.
163
163
  #
164
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
164
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
165
165
  def to_effective_config effective_config
166
166
  super
167
167
  Contrast::CONFIG.server.to_effective_config(effective_config)
@@ -218,7 +218,7 @@ module Contrast
218
218
  # Converts current configuration to effective config values class and appends them to
219
219
  # EffectiveConfig class.
220
220
  #
221
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
221
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
222
222
  def to_effective_config effective_config
223
223
  super
224
224
  sampling&.to_effective_config(effective_config)
@@ -34,7 +34,7 @@ module Contrast
34
34
  # Converts current configuration to effective config values class and appends them to
35
35
  # EffectiveConfig class.
36
36
  #
37
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
37
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
38
38
  def to_effective_config effective_config
39
39
  add_single_effective_value(effective_config, SPEC_KEY.to_s, disabled_rules, canon_name, NAME_PREFIX)
40
40
  end
@@ -1,7 +1,7 @@
1
1
  # Copyright (c) 2023 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/diagnostics_tools'
4
+ require 'contrast/config/diagnostics/tools'
5
5
  require 'contrast/utils/object_share'
6
6
 
7
7
  module Contrast
@@ -9,7 +9,7 @@ module Contrast
9
9
  # All components should inherit from this,
10
10
  # whether Interfaces, InstanceMethods or ClassMethods.
11
11
  module ComponentBase
12
- include Contrast::Agent::DiagnosticsConfig::DiagnosticsTools
12
+ include Contrast::Config::Diagnostics::Tools
13
13
 
14
14
  CONTRAST = 'contrast'
15
15
  ENABLE = 'enable'
@@ -84,7 +84,7 @@ module Contrast
84
84
  # Converts current configuration to effective config values class and appends them to
85
85
  # EffectiveConfig class.
86
86
  #
87
- # @param effective_config [Contrast::Agent::DiagnosticsConfig::EffectiveConfig]
87
+ # @param effective_config [Contrast::Config::Diagnostics::EffectiveConfig]
88
88
  def to_effective_config effective_config
89
89
  add_effective_config_values(effective_config, config_values, canon_name, "#{ CONTRAST }.#{ canon_name }")
90
90
  end
@@ -11,11 +11,14 @@ module Contrast
11
11
  # This component encapsulates storing the source for each entry in the config,
12
12
  # so that we can report on where the value was set from.
13
13
  class Sources
14
- ENVIRONMENT = 'ENV'
15
- CLI = 'CLI'
16
- CONTRASTUI = 'ContrastUI'
17
- DEFAULT = 'Default'
18
- YAML = 'YAML'
14
+ ENVIRONMENT_VARIABLE = 'ENV'
15
+ COMMAND_LINE = 'CLI'
16
+ CONTRAST_UI = 'ContrastUI'
17
+ DEFAULT_VALUE = 'Default'
18
+ # Order matters for the Configurations files. This is read when Agent starts up and will always go
19
+ # through the YAML as priority.
20
+ # Do not change the order!
21
+ APP_CONFIGURATION_FILE = %w[YAML YML].cs__freeze
19
22
 
20
23
  # @return [Hash]
21
24
  attr_reader :data
@@ -30,15 +33,15 @@ module Contrast
30
33
  # @param path [String] the canonical name for the config entry (such as api.proxy.enable)
31
34
  # @return [String] the source for the entry
32
35
  def get path
33
- data.dig(*parts_for(path)) || DEFAULT
36
+ data.dig(*parts_for(path)) || DEFAULT_VALUE
34
37
  rescue TypeError
35
- DEFAULT
38
+ DEFAULT_VALUE
36
39
  end
37
40
 
38
41
  # Assigns the config source for a specified config path.
39
42
  #
40
43
  # @param path [String] the canonical name for the config entry (such as api.proxy.enable)
41
- # @param [String] the source for the entry
44
+ # @param source[String] the source for the entry
42
45
  # @return [String] the source type for the entry
43
46
  def set path, source
44
47
  assign_value(data, parts_for(path), source)
@@ -64,7 +67,7 @@ module Contrast
64
67
  # @param current_level [Hash] all, or some of, the config source information
65
68
  # @param parts [Array] the parts for canonical name of the config entry
66
69
  # @param source [String] the source to be set for the specified entry
67
- # @return [Array] the path split on periods, and converted to symbols
70
+ # @return [String] the path split on periods, and converted to symbols
68
71
  def assign_value current_level, parts, source
69
72
  parts[0...-1].each do |segment|
70
73
  current_level[segment] ||= {}