lib/contrast/components/config.rb in contrast-agent-4.12.0 vs lib/contrast/components/config.rb in contrast-agent-4.13.0

- old
+ new

@@ -1,9 +1,10 @@ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/utils/env_configuration_item' +require 'ougai' require 'contrast/configuration' module Contrast module Components # This component encapsulates reference to the configuration file. @@ -21,31 +22,47 @@ # Config fails fast. if it's not valid, the agent should break, and # it should break LOUDLY. Better to waste half an hour of the sysadmin's # time than to silently fail to deliver functionality. module Config CONTRAST_ENV_MARKER = 'CONTRAST__' + CONTRAST_LOG = 'contrast_agent.log' + CONTRAST_NAME = 'Contrast Agent' class Interface # :nodoc: def initialize build end - def build log: true + # Basic logger for handling configuration validation logging + # the file to log is determined by the default one or set + # by the config file, if that configuration is found + def proto_logger + @_proto_logger ||= begin + @_proto_logger = ::Ougai::Logger.new(logger_path || CONTRAST_LOG) + @_proto_logger.progname = CONTRAST_NAME + @_proto_logger.level = ::Ougai::Logging::Severity::WARN + @_proto_logger.formatter = Contrast::Logger::Format.new + @_proto_logger.formatter.datetime_format = '%Y-%m-%dT%H:%M:%S.%L%z' + @_proto_logger + end + end + + def build @_valid = nil @config = Contrast::Configuration.new env_overrides - validate(log: log) + validate end alias_method :rebuild, :build # @return [Contrast::Config::RootConfiguration] def root @config.root end def valid? - @_valid = validate(log: false) if @_valid.nil? + @_valid = validate if @_valid.nil? @_valid end def invalid? !valid? @@ -57,24 +74,32 @@ private SESSION_VARIABLES = 'Invalid configuration. '\ "Setting both application.session_id and application.session_metadata is not allowed.\n" - def validate log: false + API_URL = "Invalid configuration. Missing a required connection value 'url' is not set." + API_KEY = "Invalid configuration. Missing a required connection value 'api_key' is not set." + API_SERVICE_KEY = "Invalid configuration. Missing a required connection value 'service_tag' is not set." + API_USERNAME = "Invalid configuration. Missing a required connection value 'user_name' is not set." + def validate # The config has information about how to construct the logger. # If the config is invalid, and you want to know about it, then # you have a circular dependency if you try to log it, - # hence `log: false`. + # so we use basic proto_logger to do this job. if !session_id.empty? && !session_metadata.empty? - if log - cs__class.log_error(SESSION_VARIABLES) - else - puts SESSION_VARIABLES - end + proto_logger.error(SESSION_VARIABLES) return false end - + if bypass + msg = [] + msg << API_URL unless api_url + msg << API_KEY unless api_key + msg << API_SERVICE_KEY unless api_service_key + msg << API_USERNAME unless api_username + msg.any? { |m| proto_logger.error(m) } + return false unless msg.empty? + end true end def env_overrides # For env variables resembling CONTRAST__WHATEVER__NESTED_VALUE @@ -105,9 +130,63 @@ # # @return [String,nil] the value of the session metadata set in the # configuration, or nil if unset def session_metadata @config.application.session_metadata + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::API, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def api_url + @config.api.url + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::API, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def api_key + @config.api.api_key + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::API, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def api_service_key + @config.api.service_key + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::API, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def api_username + @config.api.user_name + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::API, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def bypass + @config.root.agent.service.bypass + end + + # Typically, the following values would be accessed through Contrast::Components::AppContext + # and Contrast::Components::Logger, but we're too early in the initialization of the Agent to use + # that mechanism, so we look it up directly for ourselves. + # + # @return [String, nil] + def logger_path + @config.root.agent.logger.path end end end end end