gitlab-org--gitlab-foss/app/models/instance_configuration.rb

190 lines
7.5 KiB
Ruby

# frozen_string_literal: true
require 'resolv'
class InstanceConfiguration
SSH_ALGORITHMS = %w(DSA ECDSA ED25519 RSA).freeze
SSH_ALGORITHMS_PATH = '/etc/ssh/'
CACHE_KEY = 'instance_configuration'
EXPIRATION_TIME = 24.hours
def settings
@configuration ||= Rails.cache.fetch(CACHE_KEY, expires_in: EXPIRATION_TIME) do
{ ssh_algorithms_hashes: ssh_algorithms_hashes,
host: host,
gitlab_pages: gitlab_pages,
ci_cd_limits: ci_cd_limits,
size_limits: size_limits,
package_file_size_limits: package_file_size_limits,
rate_limits: rate_limits }.deep_symbolize_keys
end
end
private
def ssh_algorithms_hashes
SSH_ALGORITHMS.select { |algo| ssh_algorithm_enabled?(algo) }.map { |algo| ssh_algorithm_hashes(algo) }.compact
end
def ssh_algorithm_enabled?(algorithm)
algorithm_key_restriction = application_settings["#{algorithm.downcase}_key_restriction"]
algorithm_key_restriction.nil? || algorithm_key_restriction != ApplicationSetting::FORBIDDEN_KEY_VALUE
end
def host
Settings.gitlab.host
end
def gitlab_pages
Settings.pages.to_h.merge(ip_address: resolv_dns(Settings.pages.host))
end
def resolv_dns(dns)
Resolv.getaddress(dns)
rescue Resolv::ResolvError
end
def size_limits
{
max_attachment_size: application_settings[:max_attachment_size].megabytes,
receive_max_input_size: application_settings[:receive_max_input_size]&.megabytes,
max_export_size: application_settings[:max_export_size] > 0 ? application_settings[:max_export_size].megabytes : nil,
max_import_size: application_settings[:max_import_size] > 0 ? application_settings[:max_import_size].megabytes : nil,
diff_max_patch_bytes: application_settings[:diff_max_patch_bytes].bytes,
max_artifacts_size: application_settings[:max_artifacts_size].megabytes,
max_pages_size: application_settings[:max_pages_size] > 0 ? application_settings[:max_pages_size].megabytes : nil,
snippet_size_limit: application_settings[:snippet_size_limit]&.bytes
}
end
def package_file_size_limits
Plan.all.to_h { |plan| [plan.name.capitalize, plan_file_size_limits(plan)] }
end
def plan_file_size_limits(plan)
{
conan: plan.actual_limits[:conan_max_file_size],
helm: plan.actual_limits[:helm_max_file_size],
maven: plan.actual_limits[:maven_max_file_size],
npm: plan.actual_limits[:npm_max_file_size],
nuget: plan.actual_limits[:nuget_max_file_size],
pypi: plan.actual_limits[:pypi_max_file_size],
terraform_module: plan.actual_limits[:terraform_module_max_file_size],
generic: plan.actual_limits[:generic_packages_max_file_size]
}
end
def rate_limits
{
unauthenticated: {
enabled: application_settings[:throttle_unauthenticated_enabled],
requests_per_period: application_settings[:throttle_unauthenticated_requests_per_period],
period_in_seconds: application_settings[:throttle_unauthenticated_period_in_seconds]
},
authenticated_api: {
enabled: application_settings[:throttle_authenticated_api_enabled],
requests_per_period: application_settings[:throttle_authenticated_api_requests_per_period],
period_in_seconds: application_settings[:throttle_authenticated_api_period_in_seconds]
},
authenticated_web: {
enabled: application_settings[:throttle_authenticated_web_enabled],
requests_per_period: application_settings[:throttle_authenticated_web_requests_per_period],
period_in_seconds: application_settings[:throttle_authenticated_web_period_in_seconds]
},
protected_paths: {
enabled: application_settings[:throttle_protected_paths_enabled],
requests_per_period: application_settings[:throttle_protected_paths_requests_per_period],
period_in_seconds: application_settings[:throttle_protected_paths_period_in_seconds]
},
unauthenticated_packages_api: {
enabled: application_settings[:throttle_unauthenticated_packages_api_enabled],
requests_per_period: application_settings[:throttle_unauthenticated_packages_api_requests_per_period],
period_in_seconds: application_settings[:throttle_unauthenticated_packages_api_period_in_seconds]
},
authenticated_packages_api: {
enabled: application_settings[:throttle_authenticated_packages_api_enabled],
requests_per_period: application_settings[:throttle_authenticated_packages_api_requests_per_period],
period_in_seconds: application_settings[:throttle_authenticated_packages_api_period_in_seconds]
},
authenticated_git_lfs_api: {
enabled: application_settings[:throttle_authenticated_git_lfs_enabled],
requests_per_period: application_settings[:throttle_authenticated_git_lfs_requests_per_period],
period_in_seconds: application_settings[:throttle_authenticated_git_lfs_period_in_seconds]
},
issue_creation: application_setting_limit_per_minute(:issues_create_limit),
note_creation: application_setting_limit_per_minute(:notes_create_limit),
project_export: application_setting_limit_per_minute(:project_export_limit),
project_export_download: application_setting_limit_per_minute(:project_download_export_limit),
project_import: application_setting_limit_per_minute(:project_import_limit),
group_export: application_setting_limit_per_minute(:group_export_limit),
group_export_download: application_setting_limit_per_minute(:group_download_export_limit),
group_import: application_setting_limit_per_minute(:group_import_limit),
raw_blob: application_setting_limit_per_minute(:raw_blob_request_limit),
search_rate_limit: application_setting_limit_per_minute(:search_rate_limit),
search_rate_limit_unauthenticated: application_setting_limit_per_minute(:search_rate_limit_unauthenticated),
users_get_by_id: {
enabled: application_settings[:users_get_by_id_limit] > 0,
requests_per_period: application_settings[:users_get_by_id_limit],
period_in_seconds: 10.minutes
}
}
end
def ci_cd_limits
Plan.all.to_h { |plan| [plan.name.capitalize, plan_ci_cd_limits(plan)] }
end
def plan_ci_cd_limits(plan)
plan.actual_limits.slice(
:ci_pipeline_size,
:ci_active_jobs,
:ci_active_pipelines,
:ci_project_subscriptions,
:ci_pipeline_schedules,
:ci_needs_size_limit,
:ci_registered_group_runners,
:ci_registered_project_runners
)
end
def ssh_algorithm_file(algorithm)
File.join(SSH_ALGORITHMS_PATH, "ssh_host_#{algorithm.downcase}_key.pub")
end
def ssh_algorithm_hashes(algorithm)
content = ssh_algorithm_file_content(algorithm)
return unless content.present?
{ name: algorithm,
md5: ssh_algorithm_md5(content),
sha256: ssh_algorithm_sha256(content) }
end
def ssh_algorithm_file_content(algorithm)
file = ssh_algorithm_file(algorithm)
return unless File.exist?(file)
File.read(file)
end
def ssh_algorithm_md5(ssh_file_content)
Gitlab::SSHPublicKey.new(ssh_file_content).fingerprint
end
def ssh_algorithm_sha256(ssh_file_content)
Gitlab::SSHPublicKey.new(ssh_file_content).fingerprint_sha256
end
def application_settings
Gitlab::CurrentSettings.current_application_settings
end
def application_setting_limit_per_minute(setting)
{
enabled: application_settings[setting] > 0,
requests_per_period: application_settings[setting],
period_in_seconds: 1.minute
}
end
end