Project

General

Profile

Download (17 KB) Statistics
| Branch: | Tag: | Revision:
if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/jenkins/).any?
ENV['RAILS_ENV'] ||= 'test'
end
require File.expand_path('boot', __dir__)
require 'apipie/middleware/checksum_in_headers'

# Only import the frameworks we need - this list is taken from rails/all
require "rails"

[
'active_record/railtie',
# 'active_storage/engine',
'action_controller/railtie',
'action_view/railtie',
'action_mailer/railtie',
'active_job/railtie',
# 'action_cable/engine',
# 'action_mailbox/engine',
# 'action_text/engine',
'rails/test_unit/railtie',
'sprockets/railtie',
].each do |railtie|
require railtie
end

require File.expand_path('../config/settings', __dir__)
require File.expand_path('../lib/foreman/dynflow', __dir__)

if File.exist?(File.expand_path('../Gemfile.in', __dir__))
# If there is a Gemfile.in file, we will not use Bundler but BundlerExt
# gem which parses this file and loads all dependencies from the system
# rathern then trying to download them from rubygems.org. It always
# loads all gemfile groups.
require 'bundler_ext'
Bundler.ui = Bundler::UI::Silent.new if Rails.env.production?
BundlerExt.system_require(File.expand_path('../Gemfile.in', __dir__), :all)

class Foreman::Consoletie < Rails::Railtie
console { Foreman.setup_console }
end
else
# If you have a Gemfile, require the gems listed there
# Note that :default, :test, :development and :production groups
# will be included by default (and dependending on the current environment)
if defined?(Bundler)
Bundler.ui = Bundler::UI::Silent.new if Rails.env.production?

class Foreman::Consoletie < Rails::Railtie
console do
begin
Bundler.require(:console)
rescue LoadError
# no action, logs a warning in setup_console only
end
Foreman.setup_console
end
end
Bundler.require(*Rails.groups)
optional_bundler_groups = %w[assets ec2 fog libvirt openstack ovirt vmware redis]
optional_bundler_groups.each do |group|
Bundler.require(group)
rescue LoadError
# ignoring intentionally
end
end
end

# CRs in fog core with extra dependencies will have those deps loaded, so then
# load the corresponding bit of fog
require 'fog/ovirt' if defined?(::OVIRT)

require File.expand_path('../lib/foreman', __dir__)
require File.expand_path('../lib/foreman/exception', __dir__)
require File.expand_path('../lib/core_extensions', __dir__)
require File.expand_path('../lib/foreman/force_ssl', __dir__)
require File.expand_path('../lib/foreman/logging', __dir__)
require File.expand_path('../lib/foreman/http_proxy', __dir__)
require File.expand_path('../lib/foreman/middleware/logging_context_request', __dir__)
require File.expand_path('../lib/foreman/middleware/logging_context_session', __dir__)
require File.expand_path('../lib/foreman/middleware/telemetry', __dir__)
require File.expand_path('../lib/foreman/middleware/libvirt_connection_cleaner', __dir__)

# Ensure ApplicationRecord is loaded early and can be used inside migrations.
# Can probably be removed once we migrate to Zeitwerk.
require File.expand_path('../app/models/concerns/host_mix', __dir__)
require File.expand_path('../app/models/concerns/has_many_common', __dir__)
require File.expand_path('../app/models/concerns/strip_whitespace', __dir__)
require File.expand_path('../app/models/concerns/parameterizable', __dir__)
require File.expand_path('../app/models/concerns/audit_associations', __dir__)
require File.expand_path('../app/models/application_record', __dir__)

if SETTINGS[:support_jsonp]
if File.exist?(File.expand_path('../Gemfile.in', __dir__))
BundlerExt.system_require(File.expand_path('../Gemfile.in', __dir__), :jsonp)
else
Bundler.require(:jsonp)
end
end

module Foreman
class Application < Rails::Application
config.load_defaults '6.1'

# Rails 5.0 changed this to true, but a lot of code depends on this
config.active_record.belongs_to_required_by_default = false

# Rails 5.1 changed this to false, re-enabling this due to https://github.com/theforeman/foreman/pull/9711/files#r1247901552
config.assets.unknown_asset_fallback = true

# Rails 5.2 changed this to true, but we already do this in app/controllers/application_controller.rb#7
# We don't use this default because it's applied to ActionController::Base, thus to all inherited controllers
# But for API controllers we use a modification: app/controllers/concerns/foreman/controller/api_csrf_protection.rb#7
config.action_controller.default_protect_from_forgery = false
# Rails 5.2 changed this to true, but the only thing it does currently (as of Rails 7.0) is
# changing default cipher from aes-256-cbc to aes-256-gcm.
# Leaving this disabled, since the application worked with aes-256-cbc.
# Failed tests on aes-256-gcm require revisit application to ensure we can do the switch.
config.active_support.use_authenticated_message_encryption = false
config.action_dispatch.use_authenticated_cookie_encryption = false

# Rails 6.0 changed this to :zeitwerk
config.autoloader = :classic

# Rails 6.1 changed this to true, but apparently our codebase is not ready for bidirectional associations
config.active_record.has_many_inversing = false
# Setup additional routes by loading all routes file from routes directory
Dir["#{Rails.root}/config/routes/**/*.rb"].each do |route_file|
config.paths['config/routes.rb'] << route_file
end

# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.

# Autoloading
config.autoload_paths += %W(#{config.root}/app/models/auth_sources)
config.autoload_paths += %W(#{config.root}/app/models/compute_resources)
config.autoload_paths += %W(#{config.root}/app/models/fact_names)
config.autoload_paths += %W(#{config.root}/app/models/lookup_keys)
config.autoload_paths += %W(#{config.root}/app/models/host_status)
config.autoload_paths += %W(#{config.root}/app/models/operatingsystems)
config.autoload_paths += %W(#{config.root}/app/models/parameters)
config.autoload_paths += %W(#{config.root}/app/models/taxonomies)
config.autoload_paths += %W(#{config.root}/app/models/mail_notifications)

# Custom directories that will only be loaded once
# Should only contain classes with class-level data set by initializers (registries etc.)
config.autoload_once_paths += %W(#{config.root}/app/registries)

# Eager load all classes under lib directory
config.eager_load_paths += ["#{config.root}/lib"]

# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]

config.force_ssl = SETTINGS[:require_ssl]
config.ssl_options = {
redirect: {
exclude: ->(request) { Foreman::ForceSsl.new(request).allows_http? },
},
}

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
config.time_zone = 'UTC'

# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de

# Don't enforce known locales with exceptions, as fast_gettext has a fallback to default 'en'
config.i18n.enforce_available_locales = false

# Disable fieldWithErrors divs
config.action_view.field_error_proc = proc { |html_tag, instance| html_tag.to_s.html_safe }

# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"

# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password, :account_password, :facts, :root_pass, :value, :report, :password_confirmation, :secret]

# Enable escaping HTML in JSON.
config.active_support.escape_html_entities_in_json = true

# Don't raise exception for common parameters
config.action_controller.always_permitted_parameters = %w(
controller action format locale utf8 _method authenticity_token commit redirect
page per_page paginate search order sort sort_by sort_order
_ _ie_support fakepassword apiv id organization_id location_id user_id
)

# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
# like if you have constraints or database-specific column types
config.active_record.schema_format = :sql

# Starting 6.1.6.1 Rails forced users to explicitly list all the classes
# that are allowed to be loaded by Psych
# (https://github.com/rails/rails/pull/45584#issuecomment-1183255990)
config.active_record.yaml_column_permitted_classes = [
Symbol,
Time,
ActiveSupport::HashWithIndifferentAccess,
ActiveSupport::TimeZone,
ActiveSupport::TimeWithZone,
]

# enables JSONP support in the Rack middleware
config.middleware.use Rack::JSONP if SETTINGS[:support_jsonp]

# Enable Rack OpenID middleware
begin
require 'rack/openid'
require 'openid/store/filesystem'
openid_store_path = Pathname.new(Rails.root).join('db').join('openid-store')
config.middleware.use Rack::OpenID, OpenID::Store::Filesystem.new(openid_store_path)
rescue LoadError
nil
end

begin
if SETTINGS[:telemetry].try(:fetch, :prometheus).try(:fetch, :enabled)
require 'prometheus/middleware/exporter'
config.middleware.use Prometheus::Middleware::Exporter
end
rescue LoadError, KeyError
# not configured or bundler group 'telemetry' was disabled
end

# Enable the asset pipeline
config.assets.enabled = true

# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'

# Disable noisy logging of requests for assets
config.assets.quiet = true

# When operating behind a reverse proxy, this provides a valid remote ip in request.remote_ip
# the middleware is enabled by default however we minimize the trusted proxies list
#
# the trusted proxies are removed from remote IP candidates, since we know they are proxies and not clients
# in the default deployment, this is typically an Apache
#
# currently the requests with untrusted IPs in X_FORWARDED_FOR are taken into the consideration,
# the spoof detection based on HTTP_CLIENT_IP header performed by the middleware does not work
config.action_dispatch.trusted_proxies = SETTINGS.fetch(:trusted_proxies, %w(127.0.0.1/8 ::1)).map { |proxy| IPAddr.new(proxy) }

# Record request and session tokens in logging MDC
config.middleware.insert_before Rails::Rack::Logger, Foreman::Middleware::LoggingContextRequest
config.middleware.insert_after ActionDispatch::Session::ActiveRecordStore, Foreman::Middleware::LoggingContextSession

# Add apidoc hash in headers for smarter caching
config.middleware.use Apipie::Middleware::ChecksumInHeaders

# Add telemetry and connection cleaner
config.middleware.use Foreman::Middleware::Telemetry
config.middleware.use Foreman::Middleware::LibvirtConnectionCleaner

# New config option to opt out of params "deep munging" that was used to address security vulnerability CVE-2013-0155.
config.action_dispatch.perform_deep_munge = false

# Use Dynflow as the backend for ActiveJob
config.active_job.queue_adapter = :dynflow

config.action_dispatch.return_only_media_type_on_content_type = false

Foreman::Logging.configure(
:log_directory => "#{Rails.root}/log",
:environment => Rails.env,
:config_overrides => SETTINGS[:logging]
)

# Check that the loggers setting exist to configure the app and sql loggers
Foreman::Logging.add_loggers((SETTINGS[:loggers] || {}).reverse_merge(
:app => {:enabled => true},
:audit => {:enabled => true},
:ldap => {:enabled => false},
:permissions => {:enabled => false},
:proxy => {:enabled => false},
:sql => {:enabled => false},
:templates => {:enabled => true},
:notifications => {:enabled => true},
:background => {:enabled => true},
:dynflow => {:enabled => true},
:telemetry => {:enabled => false},
:blob => {:enabled => false},
:taxonomy => {:enabled => true},
:api_deprecations => {:enabled => true},
:sidekiq => {:enabled => true, :level => :warn}
))

config.logger = Foreman::Logging.logger('app')
# Explicitly set the log_level from our config, overriding the Rails env default
config.log_level = Foreman::Logging.logger_level('app').to_sym
config.active_record.logger = Foreman::Logging.logger('sql')

# enables in memory cache store with ttl
rails_cache_settings = SETTINGS[:rails_cache_store]
if (rails_cache_settings && rails_cache_settings[:type] == 'redis')
options = [:redis_cache_store]
redis_urls = Array.wrap(rails_cache_settings[:urls])

options << {
namespace: 'foreman',
url: redis_urls,
reconnect_attempts: ::Redis::Client::DEFAULTS[:reconnect_attempts],
}.merge(rails_cache_settings[:options] || {})

config.cache_store = options
Foreman::Logging.logger('app').info "Rails cache backend: Redis"
else
config.cache_store = :file_store, Rails.root.join('tmp', 'cache/')
Foreman::Logging.logger('app').info "Rails cache backend: File"
end

if config.public_file_server.enabled
::Rails::Engine.subclasses.map(&:instance).each do |engine|
if File.exist?("#{engine.root}/public/assets") || File.exist?("#{engine.root}/public/webpack")
config.middleware.use ::ActionDispatch::Static, "#{engine.root}/public"
end
end
end

if Array(SETTINGS[:cors_domains]).present?
config.middleware.insert_before 0, Rack::Cors do
allow do
origins Array(SETTINGS[:cors_domains])
resource '*', headers: :any, methods: [:get, :post, :options]
end
end
end

config.to_prepare do
# AuditExtensions contain code from app/ so can only be loaded after initializing is done
# otherwise rails auto-reloader won't be able to reload Taxonomies which are linked there
Audit.include AuditExtensions

ApplicationController.descendants.each do |child|
# reinclude the helper module in case some plugin extended some in the to_prepare phase,
# after the module was already included into controllers
helpers = child._helpers.ancestors.find_all do |ancestor|
ancestor.name =~ /Helper$/
end
child.helper helpers
end
end

# Use the database for sessions instead of the cookie-based default
config.session_store :active_record_store, :secure => !!SETTINGS[:require_ssl]

# We need to mount the sprockets engine before we use the routes_reloader
initializer(:mount_sprocket_env, :before => :sooner_routes_load) do
if config.assets.compile
app = Rails.application
if Sprockets::Railtie.instance.respond_to?(:build_environment)
app.assets = Sprockets::Railtie.instance.build_environment(app, true)
end
routes.prepend do
mount app.assets => app.config.assets.prefix
end
end
end

# We use the routes_reloader before the to_prepare and eager_load callbacks
# to make the routes load sooner than the controllers. Otherwise, the definition
# of named routes helpers in the module significantly slows down the startup
# of the application. Switching the order helps a lot.
initializer(:sooner_routes_load, :before => :run_prepare_callbacks) do
routes_reloader.execute_if_updated
end

initializer(:register_gettext, :after => :load_config_initializers) do |app|
::Foreman::Plugin.all.select { |p| p.gettext_domain }.each do |plugin|
Foreman::Gettext::Support.add_text_domain plugin.gettext_domain, plugin.locale_path
end
end

config.after_initialize do
require 'fog_extensions'

init_dynflow unless Foreman.in_rake?('db:create') || Foreman.in_rake?('db:drop')
setup_auditing
end

def dynflow
return @dynflow if @dynflow.present?
@dynflow =
if defined?(ForemanTasks)
ForemanTasks.dynflow
else
::Dynflow::Rails.new(nil, ::Foreman::Dynflow::Configuration.new)
end
@dynflow.require!
@dynflow
end

def init_dynflow
dynflow.eager_load_actions!
end

def setup_auditing
Audit.include AuditSearch
Audit.include HasManyCommon
end
end

def self.setup_console
ENV['IRBRC'] = File.expand_path('irbrc', __dir__)
User.current = User.anonymous_console_admin
Rails.logger.warn "Console started with '#{User.current.login}' user, call User.current= to change it"
end
end
(1-1/16)