Commit b55c3a7b authored by Alexis Reigel's avatar Alexis Reigel Committed by Alexis Reigel

support group runners in existing API endpoints

parent 7fbdd17c
......@@ -242,13 +242,18 @@ module API
expose :requested_at
end
class Group < Grape::Entity
expose :id, :name, :path, :description, :visibility
class BasicGroupDetails < Grape::Entity
expose :id
expose :web_url
expose :name
end
class Group < BasicGroupDetails
expose :path, :description, :visibility
expose :lfs_enabled?, as: :lfs_enabled
expose :avatar_url do |group, options|
group.avatar_url(only_path: false)
end
expose :web_url
expose :request_access_enabled
expose :full_name, :full_path
......@@ -965,6 +970,13 @@ module API
options[:current_user].authorized_projects.where(id: runner.projects)
end
end
expose :groups, with: Entities::BasicGroupDetails do |runner, options|
if options[:current_user].admin?
runner.groups
else
options[:current_user].authorized_groups.where(id: runner.groups)
end
end
end
class RunnerRegistrationDetails < Grape::Entity
......
......@@ -25,8 +25,11 @@ module API
# Create shared runner. Requires admin access
Ci::Runner.create(attributes.merge(is_shared: true))
elsif project = Project.find_by(runners_token: params[:token])
# Create a specific runner for project.
# Create a specific runner for the project
project.runners.create(attributes)
elsif group = Group.find_by(runners_token: params[:token])
# Create a specific runner for the group
group.runners.create(attributes)
end
break forbidden! unless runner
......
......@@ -199,6 +199,7 @@ module API
forbidden!("Runner is shared") if runner.is_shared?
forbidden!("Runner associated with more than one project") if runner.projects.count > 1
forbidden!("Runner associated with more that one group") if runner.groups.count > 1
forbidden!("No access granted") unless user_can_access_runner?(runner)
end
......
......@@ -54,6 +54,7 @@ module API
forbidden!("Runner is shared") if runner.is_shared?
forbidden!("Runner associated with more than one project") if runner.projects.count > 1
forbidden!("Runner associated with more that one group") if runner.groups.count > 1
forbidden!("No access granted") unless user_can_access_runner?(runner)
end
......
......@@ -45,7 +45,7 @@ describe API::Runner do
context 'when project token is used' do
let(:project) { create(:project) }
it 'creates runner' do
it 'creates project runner' do
post api('/runners'), token: project.runners_token
expect(response).to have_gitlab_http_status 201
......@@ -54,6 +54,19 @@ describe API::Runner do
expect(Ci::Runner.first.token).not_to eq(project.runners_token)
end
end
context 'when group token is used' do
let(:group) { create(:group) }
it 'creates a group runner' do
post api('/runners'), token: group.runners_token
expect(response).to have_http_status 201
expect(group.runners.size).to eq(1)
expect(Ci::Runner.first.token).not_to eq(registration_token)
expect(Ci::Runner.first.token).not_to eq(group.runners_token)
end
end
end
context 'when runner description is provided' do
......
This diff is collapsed.
......@@ -8,10 +8,16 @@ describe API::V3::Runners do
let(:project) { create(:project, creator_id: user.id) }
let(:project2) { create(:project, creator_id: user.id) }
let(:group) { create(:group).tap { |group| group.add_owner(user) } }
let(:group2) { create(:group).tap { |group| group.add_owner(user) } }
let!(:group_runner) { create(:ci_runner, description: 'Group runner', groups: [group]) }
let!(:two_groups_runner) { create(:ci_runner, description: 'Two groups runner', groups: [group, group2]) }
let!(:shared_runner) { create(:ci_runner, :shared) }
let!(:unused_specific_runner) { create(:ci_runner) }
let!(:specific_runner) do
let!(:project_runner) do
create(:ci_runner).tap do |runner|
create(:ci_runner_project, runner: runner, project: project)
end
......@@ -51,9 +57,17 @@ describe API::V3::Runners do
end.to change { Ci::Runner.specific.count }.by(-1)
end
it 'deletes used runner' do
it 'deletes used project runner' do
expect do
delete v3_api("/runners/#{specific_runner.id}", admin)
delete v3_api("/runners/#{project_runner.id}", admin)
expect(response).to have_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
end
it 'deletes used group runner' do
expect do
delete v3_api("/runners/#{group_runner.id}", admin)
expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
......@@ -77,18 +91,31 @@ describe API::V3::Runners do
context 'when runner is not shared' do
it 'does not delete runner without access to it' do
delete v3_api("/runners/#{specific_runner.id}", user2)
delete v3_api("/runners/#{project_runner.id}", user2)
expect(response).to have_gitlab_http_status(403)
end
it 'does not delete runner with more than one associated project' do
it 'does not delete project runner with more than one associated project' do
delete v3_api("/runners/#{two_projects_runner.id}", user)
expect(response).to have_gitlab_http_status(403)
end
it 'deletes runner for one owned project' do
it 'deletes project runner for one owned project' do
expect do
delete v3_api("/runners/#{specific_runner.id}", user)
delete v3_api("/runners/#{group_runner.id}", user)
expect(response).to have_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
end
it 'does not delete group runner with more than one associated project' do
delete v3_api("/runners/#{two_groups_runner.id}", user)
expect(response).to have_http_status(403)
end
it 'deletes group runner for one owned project' do
expect do
delete v3_api("/runners/#{project_runner.id}", user)
expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
......@@ -97,8 +124,14 @@ describe API::V3::Runners do
end
context 'unauthorized user' do
it 'does not delete runner' do
delete v3_api("/runners/#{specific_runner.id}")
it 'does not delete project runner' do
delete v3_api("/runners/#{project_runner.id}")
expect(response).to have_http_status(401)
end
it 'does not delete group runner' do
delete v3_api("/runners/#{group_runner.id}")
expect(response).to have_gitlab_http_status(401)
end
......@@ -120,7 +153,7 @@ describe API::V3::Runners do
context 'when runner have one associated projects' do
it "does not disable project's runner" do
expect do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}", user)
delete v3_api("/projects/#{project.id}/runners/#{project_runner.id}", user)
end.to change { project.runners.count }.by(0)
expect(response).to have_gitlab_http_status(403)
end
......@@ -135,7 +168,7 @@ describe API::V3::Runners do
context 'authorized user without permissions' do
it "does not disable project's runner" do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}", user2)
delete v3_api("/projects/#{project.id}/runners/#{project_runner.id}", user2)
expect(response).to have_gitlab_http_status(403)
end
......@@ -143,7 +176,7 @@ describe API::V3::Runners do
context 'unauthorized user' do
it "does not disable project's runner" do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}")
delete v3_api("/projects/#{project.id}/runners/#{project_runner.id}")
expect(response).to have_gitlab_http_status(401)
end
......
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