Commit 06804483 authored by Alex Pooley's avatar Alex Pooley

Merge branch 'pedropombeiro/349542/2-move-services' into 'master'

Move runner services to their own namespace

See merge request gitlab-org/gitlab!81251
parents a4273cc0 6e37e8bd
......@@ -8,7 +8,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
if ::Ci::AssignRunnerService.new(@runner, @project, current_user).execute
if ::Ci::Runners::AssignRunnerService.new(@runner, @project, current_user).execute
redirect_to edit_admin_runner_url(@runner), notice: s_('Runners|Runner assigned to project.')
else
redirect_to edit_admin_runner_url(@runner), alert: 'Failed adding runner to project'
......
......@@ -23,7 +23,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
respond_to do |format|
format.html { redirect_to edit_admin_runner_path(@runner) }
end
......@@ -34,13 +34,13 @@ class Admin::RunnersController < Admin::ApplicationController
end
def destroy
Ci::UnregisterRunnerService.new(@runner, current_user).execute
Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
redirect_to admin_runners_path, status: :found
end
def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
......@@ -48,7 +48,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
......
......@@ -24,7 +24,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to group_runner_path(@group, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
......@@ -35,14 +35,14 @@ class Groups::RunnersController < Groups::ApplicationController
if @runner.belongs_to_more_than_one_project?
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found, alert: _('Runner was not deleted because it is assigned to multiple projects.')
else
Ci::UnregisterRunnerService.new(@runner, current_user).execute
Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found
end
end
def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: _('Runner was successfully updated.')
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: _('Runner was not updated.')
......@@ -50,7 +50,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: _('Runner was successfully updated.')
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: _('Runner was not updated.')
......
......@@ -14,7 +14,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
path = project_runners_path(project)
if ::Ci::AssignRunnerService.new(@runner, @project, current_user).execute
if ::Ci::Runners::AssignRunnerService.new(@runner, @project, current_user).execute
redirect_to path, notice: s_('Runners|Runner assigned to project.')
else
assign_to_messages = @runner.errors.messages[:assign_to]
......
......@@ -14,7 +14,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to project_runner_path(@project, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
......@@ -23,14 +23,14 @@ class Projects::RunnersController < Projects::ApplicationController
def destroy
if @runner.only_for?(project)
Ci::UnregisterRunnerService.new(@runner, current_user).execute
Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
end
redirect_to project_runners_path(@project), status: :found
end
def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
......@@ -38,7 +38,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false)
if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
......
......@@ -20,7 +20,7 @@ module Mutations
error = authenticate_delete_runner!(runner)
return { errors: [error] } if error
::Ci::UnregisterRunnerService.new(runner, current_user).execute
::Ci::Runners::UnregisterRunnerService.new(runner, current_user).execute
{ errors: runner.errors.full_messages }
end
......
......@@ -53,7 +53,7 @@ module Mutations
def resolve(id:, **runner_attrs)
runner = authorized_find!(id)
unless ::Ci::UpdateRunnerService.new(runner).update(runner_attrs)
unless ::Ci::Runners::UpdateRunnerService.new(runner).update(runner_attrs)
return { runner: nil, errors: runner.errors.full_messages }
end
......
# frozen_string_literal: true
module Ci
class AssignRunnerService
# @param [Ci::Runner] runner the runner to assign to a project
# @param [Project] project the new project to assign the runner to
# @param [User] user the user performing the operation
def initialize(runner, project, user)
@runner = runner
@project = project
@user = user
end
def execute
return false unless @user.present? && @user.can?(:assign_runner, @runner)
@runner.assign_to(@project, @user)
end
end
end
# frozen_string_literal: true
module Ci
class RegisterRunnerService
def execute(registration_token, attributes)
runner_type_attrs = extract_runner_type_attrs(registration_token)
return unless runner_type_attrs
::Ci::Runner.create(attributes.merge(runner_type_attrs))
end
private
def extract_runner_type_attrs(registration_token)
@attrs_from_token ||= check_token(registration_token)
return unless @attrs_from_token
attrs = @attrs_from_token.clone
case attrs[:runner_type]
when :project_type
attrs[:projects] = [attrs.delete(:scope)]
when :group_type
attrs[:groups] = [attrs.delete(:scope)]
end
attrs
end
def check_token(registration_token)
if runner_registration_token_valid?(registration_token)
# Create shared runner. Requires admin access
{ runner_type: :instance_type }
elsif runner_registrar_valid?('project') && project = ::Project.find_by_runners_token(registration_token)
# Create a specific runner for the project
{ runner_type: :project_type, scope: project }
elsif runner_registrar_valid?('group') && group = ::Group.find_by_runners_token(registration_token)
# Create a specific runner for the group
{ runner_type: :group_type, scope: group }
end
end
def runner_registration_token_valid?(registration_token)
ActiveSupport::SecurityUtils.secure_compare(registration_token, Gitlab::CurrentSettings.runners_registration_token)
end
def runner_registrar_valid?(type)
Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type)
end
def token_scope
@attrs_from_token[:scope]
end
end
end
Ci::RegisterRunnerService.prepend_mod
# frozen_string_literal: true
module Ci
module Runners
class AssignRunnerService
# @param [Ci::Runner] runner the runner to assign to a project
# @param [Project] project the new project to assign the runner to
# @param [User] user the user performing the operation
def initialize(runner, project, user)
@runner = runner
@project = project
@user = user
end
def execute
return false unless @user.present? && @user.can?(:assign_runner, @runner)
@runner.assign_to(@project, @user)
end
end
end
end
# frozen_string_literal: true
module Ci
module Runners
class RegisterRunnerService
def execute(registration_token, attributes)
runner_type_attrs = extract_runner_type_attrs(registration_token)
return unless runner_type_attrs
::Ci::Runner.create(attributes.merge(runner_type_attrs))
end
private
def extract_runner_type_attrs(registration_token)
@attrs_from_token ||= check_token(registration_token)
return unless @attrs_from_token
attrs = @attrs_from_token.clone
case attrs[:runner_type]
when :project_type
attrs[:projects] = [attrs.delete(:scope)]
when :group_type
attrs[:groups] = [attrs.delete(:scope)]
end
attrs
end
def check_token(registration_token)
if runner_registration_token_valid?(registration_token)
# Create shared runner. Requires admin access
{ runner_type: :instance_type }
elsif runner_registrar_valid?('project') && project = ::Project.find_by_runners_token(registration_token)
# Create a specific runner for the project
{ runner_type: :project_type, scope: project }
elsif runner_registrar_valid?('group') && group = ::Group.find_by_runners_token(registration_token)
# Create a specific runner for the group
{ runner_type: :group_type, scope: group }
end
end
def runner_registration_token_valid?(registration_token)
ActiveSupport::SecurityUtils.secure_compare(registration_token, Gitlab::CurrentSettings.runners_registration_token)
end
def runner_registrar_valid?(type)
Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type)
end
def token_scope
@attrs_from_token[:scope]
end
end
end
end
Ci::Runners::RegisterRunnerService.prepend_mod
# frozen_string_literal: true
module Ci
module Runners
class UnregisterRunnerService
attr_reader :runner, :author
# @param [Ci::Runner] runner the runner to unregister/destroy
# @param [User, authentication token String] author the user or the authentication token that authorizes the removal
def initialize(runner, author)
@runner = runner
@author = author
end
def execute
@runner&.destroy
end
end
end
end
Ci::Runners::UnregisterRunnerService.prepend_mod
# frozen_string_literal: true
module Ci
module Runners
class UpdateRunnerService
attr_reader :runner
def initialize(runner)
@runner = runner
end
def update(params)
params[:active] = !params.delete(:paused) if params.include?(:paused)
runner.update(params).tap do |updated|
runner.tick_runner_queue if updated
end
end
end
end
end
# frozen_string_literal: true
module Ci
class UnregisterRunnerService
attr_reader :runner, :author
# @param [Ci::Runner] runner the runner to unregister/destroy
# @param [User, authentication token String] author the user or the authentication token that authorizes the removal
def initialize(runner, author)
@runner = runner
@author = author
end
def execute
@runner&.destroy
end
end
end
Ci::UnregisterRunnerService.prepend_mod
# frozen_string_literal: true
module Ci
class UpdateRunnerService
attr_reader :runner
def initialize(runner)
@runner = runner
end
def update(params)
params[:active] = !params.delete(:paused) if params.include?(:paused)
runner.update(params).tap do |updated|
runner.tick_runner_queue if updated
end
end
end
end
# frozen_string_literal: true
module EE
module Ci
module RegisterRunnerService
extend ::Gitlab::Utils::Override
include ::Audit::Changes
override :execute
def execute(registration_token, attributes)
runner = super(registration_token, attributes)
audit_log_event(runner, registration_token) if runner
runner
end
private
def audit_log_event(runner, registration_token)
::AuditEvents::RegisterRunnerAuditEventService.new(runner, registration_token, token_scope)
.track_event
end
end
end
end
# frozen_string_literal: true
module EE
module Ci
module Runners
module RegisterRunnerService
extend ::Gitlab::Utils::Override
include ::Audit::Changes
override :execute
def execute(registration_token, attributes)
runner = super(registration_token, attributes)
audit_log_event(runner, registration_token) if runner
runner
end
private
def audit_log_event(runner, registration_token)
::AuditEvents::RegisterRunnerAuditEventService.new(runner, registration_token, token_scope)
.track_event
end
end
end
end
end
# frozen_string_literal: true
module EE
module Ci
module Runners
# Unregisters a CI Runner and logs an audit event
#
module UnregisterRunnerService
extend ::Gitlab::Utils::Override
include ::Audit::Changes
override :execute
def execute
scopes = runner_scopes # Save the scopes before destroying the record
result = super
audit_log_event(scopes)
result
end
private
def runner_scopes
case runner.runner_type
when 'instance_type'
[nil]
when 'group_type'
runner.groups.to_a
when 'project_type'
runner.projects.to_a
end
end
def audit_log_event(scopes)
scopes.each do |scope|
::AuditEvents::UnregisterRunnerAuditEventService.new(runner, author, scope)
.track_event
end
end
end
end
end
end
# frozen_string_literal: true
module EE
module Ci
# Unregisters a CI Runner and logs an audit event
#
module UnregisterRunnerService
extend ::Gitlab::Utils::Override
include ::Audit::Changes
override :execute
def execute
scopes = runner_scopes # Save the scopes before destroying the record
result = super
audit_log_event(scopes)
result
end
private
def runner_scopes
case runner.runner_type
when 'instance_type'
[nil]
when 'group_type'
runner.groups.to_a
when 'project_type'
runner.projects.to_a
end
end
def audit_log_event(scopes)
scopes.each do |scope|
::AuditEvents::UnregisterRunnerAuditEventService.new(runner, author, scope)
.track_event
end
end
end
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ci::RegisterRunnerService, '#execute' do
RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do
let(:registration_token) { 'abcdefg123456' }
let(:token) { }
let(:audit_service) { instance_double(::AuditEvents::RegisterRunnerAuditEventService) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ci::UnregisterRunnerService, '#execute' do
RSpec.describe ::Ci::Runners::UnregisterRunnerService, '#execute' do
let(:audit_service) { instance_double(::AuditEvents::UnregisterRunnerAuditEventService) }
let(:current_user) { nil }
let(:token) { 'abc123' }
......
......@@ -38,7 +38,7 @@ module API
attributes[:maintenance_note] ||= deprecated_note if deprecated_note
attributes[:active] = !attributes.delete(:paused) if attributes.include?(:paused)
@runner = ::Ci::RegisterRunnerService.new.execute(params[:token], attributes)
@runner = ::Ci::Runners::RegisterRunnerService.new.execute(params[:token], attributes)
forbidden! unless @runner
if @runner.persisted?
......@@ -57,7 +57,7 @@ module API
delete '/', feature_category: :runner do
authenticate_runner!
destroy_conditionally!(current_runner) { ::Ci::UnregisterRunnerService.new(current_runner, params[:token]).execute }
destroy_conditionally!(current_runner) { ::Ci::Runners::UnregisterRunnerService.new(current_runner, params[:token]).execute }
end
desc 'Validates authentication credentials' do
......
......@@ -90,7 +90,7 @@ module API
runner = get_runner(params.delete(:id))
authenticate_update_runner!(runner)
params[:active] = !params.delete(:paused) if params.include?(:paused)
update_service = ::Ci::UpdateRunnerService.new(runner)
update_service = ::Ci::Runners::UpdateRunnerService.new(runner)
if update_service.update(declared_params(include_missing: false))
present runner, with: Entities::Ci::RunnerDetails, current_user: current_user
......@@ -110,7 +110,7 @@ module API
authenticate_delete_runner!(runner)
destroy_conditionally!(runner) { ::Ci::UnregisterRunnerService.new(runner, current_user).execute }
destroy_conditionally!(runner) { ::Ci::Runners::UnregisterRunnerService.new(runner, current_user).execute }
end
desc 'List jobs running on a runner' do
......@@ -187,7 +187,7 @@ module API
runner = get_runner(params[:runner_id])
authenticate_enable_runner!(runner)
if ::Ci::AssignRunnerService.new(runner, user_project, current_user).execute
if ::Ci::Runners::AssignRunnerService.new(runner, user_project, current_user).execute
present runner, with: Entities::Ci::Runner
else
render_validation_error!(runner)
......
......@@ -105,7 +105,7 @@ RSpec.describe Admin::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
expect_next_instance_of(Ci::UnregisterRunnerService, runner, user) do |service|
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......
......@@ -190,7 +190,7 @@ RSpec.describe Groups::RunnersController do
end
it 'destroys the runner and redirects' do
expect_next_instance_of(Ci::UnregisterRunnerService, runner, user) do |service|
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......
......@@ -37,7 +37,7 @@ RSpec.describe Projects::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
expect_next_instance_of(Ci::UnregisterRunnerService, runner, user) do |service|
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......
......@@ -55,7 +55,7 @@ RSpec.describe Mutations::Ci::Runner::Delete do
it 'deletes runner' do
mutation_params[:id] = project_runner.to_global_id
expect_next_instance_of(::Ci::UnregisterRunnerService, project_runner, current_ctx[:current_user]) do |service|
expect_next_instance_of(::Ci::Runners::UnregisterRunnerService, project_runner, current_ctx[:current_user]) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......@@ -75,7 +75,7 @@ RSpec.describe Mutations::Ci::Runner::Delete do
it 'does not delete project runner' do
mutation_params[:id] = two_projects_runner.to_global_id
allow_next_instance_of(::Ci::UnregisterRunnerService) do |service|
allow_next_instance_of(::Ci::Runners::UnregisterRunnerService) do |service|
expect(service).not_to receive(:execute)
end
expect { subject }.not_to change { Ci::Runner.count }
......@@ -89,7 +89,7 @@ RSpec.describe Mutations::Ci::Runner::Delete do
let(:current_ctx) { { current_user: admin_user } }
it 'deletes runner' do
expect_next_instance_of(::Ci::UnregisterRunnerService, runner, current_ctx[:current_user]) do |service|
expect_next_instance_of(::Ci::Runners::UnregisterRunnerService, runner, current_ctx[:current_user]) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......
......@@ -951,7 +951,7 @@ RSpec.describe Ci::Runner do
let!(:last_update) { runner.ensure_runner_queue_value }
before do
Ci::UpdateRunnerService.new(runner).update(description: 'new runner') # rubocop: disable Rails/SaveBang
Ci::Runners::UpdateRunnerService.new(runner).update(description: 'new runner') # rubocop: disable Rails/SaveBang
end
it 'sets a new last_update value' do
......
......@@ -15,7 +15,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context 'when invalid token is provided' do
it 'returns 403 error' do
allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
allow(service).to receive(:execute).and_return(nil)
end
......@@ -43,7 +43,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let_it_be(:new_runner) { create(:ci_runner) }
before do
allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expected_params = {
description: 'server.hostname',
maintenance_note: 'Some maintainer notes',
......@@ -108,7 +108,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let(:new_runner) { create(:ci_runner) }
it 'converts to maintenance_note param' do
allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expect(service).to receive(:execute)
.once
.with('valid token', a_hash_including('maintenance_note' => 'Some maintainer notes')
......@@ -133,7 +133,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let_it_be(:new_runner) { create(:ci_runner) }
it 'uses active value in registration' do
expect_next_instance_of(::Ci::RegisterRunnerService) do |service|
expect_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expected_params = { active: false }.stringify_keys
expect(service).to receive(:execute)
......
......@@ -530,7 +530,7 @@ RSpec.describe API::Ci::Runners do
context 'admin user' do
context 'when runner is shared' do
it 'deletes runner' do
expect_next_instance_of(Ci::UnregisterRunnerService, shared_runner, admin) do |service|
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, shared_runner, admin) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......@@ -548,7 +548,7 @@ RSpec.describe API::Ci::Runners do
context 'when runner is not shared' do
it 'deletes used project runner' do
expect_next_instance_of(Ci::UnregisterRunnerService, project_runner, admin) do |service|
expect_next_instance_of(Ci::Runners::UnregisterRunnerService, project_runner, admin) do |service|
expect(service).to receive(:execute).once.and_call_original
end
......@@ -561,7 +561,7 @@ RSpec.describe API::Ci::Runners do
end
it 'returns 404 if runner does not exist' do
allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service|
expect(service).not_to receive(:execute)
end
......@@ -646,7 +646,7 @@ RSpec.describe API::Ci::Runners do
context 'unauthorized user' do
it 'does not delete project runner' do
allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service|
expect(service).not_to receive(:execute)
end
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ci::AssignRunnerService, '#execute' do
RSpec.describe ::Ci::Runners::AssignRunnerService, '#execute' do
subject { described_class.new(runner, project, user).execute }
let_it_be(:runner) { build(:ci_runner) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ci::RegisterRunnerService, '#execute' do
RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do
let(:registration_token) { 'abcdefg123456' }
let(:token) { }
let(:args) { {} }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe ::Ci::UnregisterRunnerService, '#execute' do
RSpec.describe ::Ci::Runners::UnregisterRunnerService, '#execute' do
subject { described_class.new(runner, 'some_token').execute }
let(:runner) { create(:ci_runner) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Ci::UpdateRunnerService do
RSpec.describe Ci::Runners::UpdateRunnerService do
let(:runner) { create(:ci_runner) }
describe '#update' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment