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