debian-mirror-gitlab/app/services/self_monitoring/project/create_service.rb
2019-10-12 21:52:04 +05:30

219 lines
6.3 KiB
Ruby

# frozen_string_literal: true
module SelfMonitoring
module Project
class CreateService < ::BaseService
include Stepable
include Gitlab::Utils::StrongMemoize
VISIBILITY_LEVEL = Gitlab::VisibilityLevel::INTERNAL
PROJECT_NAME = 'GitLab Instance Administration'
PROJECT_DESCRIPTION = <<~HEREDOC
This project is automatically generated and will be used to help monitor this GitLab instance.
HEREDOC
GROUP_NAME = 'GitLab Instance Administrators'
GROUP_PATH = 'gitlab-instance-administrators'
steps :validate_admins,
:create_group,
:create_project,
:save_project_id,
:add_group_members,
:add_to_whitelist,
:add_prometheus_manual_configuration
def initialize
super(nil)
end
def execute
execute_steps
end
private
def validate_admins
unless instance_admins.any?
log_error('No active admin user found')
return error('No active admin user found')
end
success
end
def create_group
if project_created?
log_info(_('Instance administrators group already exists'))
@group = application_settings.instance_administration_project.owner
return success(group: @group)
end
admin_user = group_owner
@group = ::Groups::CreateService.new(admin_user, create_group_params).execute
if @group.persisted?
success(group: @group)
else
error('Could not create group')
end
end
def create_project
if project_created?
log_info(_('Instance administration project already exists'))
@project = application_settings.instance_administration_project
return success(project: project)
end
admin_user = group_owner
@project = ::Projects::CreateService.new(admin_user, create_project_params).execute
if project.persisted?
success(project: project)
else
log_error(_("Could not create instance administration project. Errors: %{errors}") % { errors: project.errors.full_messages })
error(_('Could not create project'))
end
end
def save_project_id
return success if project_created?
result = ApplicationSettings::UpdateService.new(
application_settings,
group_owner,
{ instance_administration_project_id: @project.id }
).execute
if result
success
else
log_error(_("Could not save instance administration project ID, errors: %{errors}") % { errors: application_settings.errors.full_messages })
error(_('Could not save project ID'))
end
end
def add_group_members
members = @group.add_users(group_maintainers, Gitlab::Access::MAINTAINER)
errors = members.flat_map { |member| member.errors.full_messages }
if errors.any?
log_error("Could not add admins as members to self-monitoring project. Errors: #{errors}")
error('Could not add admins as members')
else
success
end
end
def add_to_whitelist
return success unless prometheus_enabled?
return success unless prometheus_listen_address.present?
uri = parse_url(internal_prometheus_listen_address_uri)
return error(_('Prometheus listen_address is not a valid URI')) unless uri
result = ApplicationSettings::UpdateService.new(
application_settings,
group_owner,
add_to_outbound_local_requests_whitelist: [uri.normalized_host]
).execute
if result
success
else
log_error(_("Could not add prometheus URL to whitelist, errors: %{errors}") % { errors: application_settings.errors.full_messages })
error(_('Could not add prometheus URL to whitelist'))
end
end
def add_prometheus_manual_configuration
return success unless prometheus_enabled?
return success unless prometheus_listen_address.present?
service = project.find_or_initialize_service('prometheus')
unless service.update(prometheus_service_attributes)
log_error("Could not save prometheus manual configuration for self-monitoring project. Errors: #{service.errors.full_messages}")
return error('Could not save prometheus manual configuration')
end
success
end
def application_settings
strong_memoize(:application_settings) do
Gitlab::CurrentSettings.expire_current_application_settings
Gitlab::CurrentSettings.current_application_settings
end
end
def project_created?
application_settings.instance_administration_project.present?
end
def parse_url(uri_string)
Addressable::URI.parse(uri_string)
rescue Addressable::URI::InvalidURIError, TypeError
end
def prometheus_enabled?
Gitlab.config.prometheus.enable
rescue Settingslogic::MissingSetting
false
end
def prometheus_listen_address
Gitlab.config.prometheus.listen_address
rescue Settingslogic::MissingSetting
end
def instance_admins
@instance_admins ||= User.admins.active
end
def group_owner
instance_admins.first
end
def group_maintainers
# Exclude the first so that the group_owner is not added again as a member.
instance_admins - [group_owner]
end
def create_group_params
{
name: GROUP_NAME,
path: "#{GROUP_PATH}-#{SecureRandom.hex(4)}",
visibility_level: VISIBILITY_LEVEL
}
end
def create_project_params
{
initialize_with_readme: true,
visibility_level: VISIBILITY_LEVEL,
name: PROJECT_NAME,
description: PROJECT_DESCRIPTION,
namespace_id: @group.id
}
end
def internal_prometheus_listen_address_uri
if prometheus_listen_address.starts_with?('http')
prometheus_listen_address
else
'http://' + prometheus_listen_address
end
end
def prometheus_service_attributes
{
api_url: internal_prometheus_listen_address_uri,
manual_configuration: true,
active: true
}
end
end
end
end