Commit dc0bd190 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'improve_storage_move_workflow' into 'master'

Add project specific repository storage API

See merge request gitlab-org/gitlab!32493
parents d0a19916 5a74d3d7
---
title: Add project specific repository storage API
merge_request: 32493
author:
type: added
...@@ -41,17 +41,60 @@ Example response: ...@@ -41,17 +41,60 @@ Example response:
] ]
``` ```
## Retrieve all repository storage moves for a project
```plaintext
GET /projects/:project_id/repository_storage_moves
```
By default, `GET` requests return 20 results at a time because the API results
are [paginated](README.md#pagination).
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `project_id` | integer | yes | The ID of the project |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://primary.example.com/api/v4/project/1/repository_storage_moves'
```
Example response:
```json
[
{
"id": 1,
"created_at": "2020-05-07T04:27:17.234Z",
"state": "scheduled",
"source_storage_name": "default",
"destination_storage_name": "storage2",
"project": {
"id": 1,
"description": null,
"name": "project1",
"name_with_namespace": "John Doe2 / project1",
"path": "project1",
"path_with_namespace": "namespace1/project1",
"created_at": "2020-05-07T04:27:17.016Z"
}
]
```
## Get a single project repository storage move ## Get a single project repository storage move
```plaintext ```plaintext
GET /project_repository_storage_moves/:id GET /project_repository_storage_moves/:repository_storage_id
``` ```
Parameters: Parameters:
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- | | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of the project repository storage move | | `repository_storage_id` | integer | yes | The ID of the project repository storage move |
Example request: Example request:
...@@ -78,3 +121,42 @@ Example response: ...@@ -78,3 +121,42 @@ Example response:
"created_at": "2020-05-07T04:27:17.016Z" "created_at": "2020-05-07T04:27:17.016Z"
} }
``` ```
## Get a single repository storage move for a project
```plaintext
GET /project/:project_id/repository_storage_moves/:repository_storage_id
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `project_id` | integer | yes | The ID of the project |
| `repository_storage_id` | integer | yes | The ID of the project repository storage move |
Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://primary.example.com/api/v4/project/1/repository_storage_moves/1'
```
Example response:
```json
{
"id": 1,
"created_at": "2020-05-07T04:27:17.234Z",
"state": "scheduled",
"source_storage_name": "default",
"destination_storage_name": "storage2",
"project": {
"id": 1,
"description": null,
"name": "project1",
"name_with_namespace": "John Doe2 / project1",
"path": "project1",
"path_with_namespace": "namespace1/project1",
"created_at": "2020-05-07T04:27:17.016Z"
}
```
...@@ -24,8 +24,42 @@ module API ...@@ -24,8 +24,42 @@ module API
detail 'This feature was introduced in GitLab 13.0.' detail 'This feature was introduced in GitLab 13.0.'
success Entities::ProjectRepositoryStorageMove success Entities::ProjectRepositoryStorageMove
end end
get ':id' do params do
storage_move = ProjectRepositoryStorageMove.find(params[:id]) requires :repository_storage_move_id, type: Integer, desc: 'The ID of a project repository storage move'
end
get ':repository_storage_move_id' do
storage_move = ProjectRepositoryStorageMove.find(params[:repository_storage_move_id])
present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user
end
end
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a list of all project repository storage moves' do
detail 'This feature was introduced in GitLab 13.1.'
success Entities::ProjectRepositoryStorageMove
end
params do
use :pagination
end
get ':id/repository_storage_moves' do
storage_moves = user_project.repository_storage_moves.with_projects.order_created_at_desc
present paginate(storage_moves), with: Entities::ProjectRepositoryStorageMove, current_user: current_user
end
desc 'Get a project repository storage move' do
detail 'This feature was introduced in GitLab 13.1.'
success Entities::ProjectRepositoryStorageMove
end
params do
requires :repository_storage_move_id, type: Integer, desc: 'The ID of a project repository storage move'
end
get ':id/repository_storage_moves/:repository_storage_move_id' do
storage_move = user_project.repository_storage_moves.find(params[:repository_storage_move_id])
present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user present storage_move, with: Entities::ProjectRepositoryStorageMove, current_user: current_user
end end
......
...@@ -5,12 +5,45 @@ require 'spec_helper' ...@@ -5,12 +5,45 @@ require 'spec_helper'
describe API::ProjectRepositoryStorageMoves do describe API::ProjectRepositoryStorageMoves do
include AccessMatchersForRequest include AccessMatchersForRequest
let(:user) { create(:admin) } let_it_be(:user) { create(:admin) }
let!(:storage_move) { create(:project_repository_storage_move, :scheduled) } let_it_be(:project) { create(:project) }
let_it_be(:storage_move) { create(:project_repository_storage_move, :scheduled, project: project) }
describe 'GET /project_repository_storage_moves' do shared_examples 'get single project repository storage move' do
let(:project_repository_storage_move_id) { storage_move.id }
def get_project_repository_storage_move
get api(url, user)
end
it 'returns a project repository storage move' do
get_project_repository_storage_move
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/project_repository_storage_move')
expect(json_response['id']).to eq(storage_move.id)
expect(json_response['state']).to eq(storage_move.human_state_name)
end
context 'non-existent project repository storage move' do
let(:project_repository_storage_move_id) { non_existing_record_id }
it 'returns not found' do
get_project_repository_storage_move
expect(response).to have_gitlab_http_status(:not_found)
end
end
describe 'permissions' do
it { expect { get_project_repository_storage_move }.to be_allowed_for(:admin) }
it { expect { get_project_repository_storage_move }.to be_denied_for(:user) }
end
end
shared_examples 'get project repository storage move list' do
def get_project_repository_storage_moves def get_project_repository_storage_moves
get api('/project_repository_storage_moves', user) get api(url, user)
end end
it 'returns project repository storage moves' do it 'returns project repository storage moves' do
...@@ -30,16 +63,16 @@ describe API::ProjectRepositoryStorageMoves do ...@@ -30,16 +63,16 @@ describe API::ProjectRepositoryStorageMoves do
control = ActiveRecord::QueryRecorder.new { get_project_repository_storage_moves } control = ActiveRecord::QueryRecorder.new { get_project_repository_storage_moves }
create(:project_repository_storage_move, :scheduled) create(:project_repository_storage_move, :scheduled, project: project)
expect { get_project_repository_storage_moves }.not_to exceed_query_limit(control) expect { get_project_repository_storage_moves }.not_to exceed_query_limit(control)
end end
it 'returns the most recently created first' do it 'returns the most recently created first' do
storage_move_oldest = create(:project_repository_storage_move, :scheduled, created_at: 2.days.ago) storage_move_oldest = create(:project_repository_storage_move, :scheduled, project: project, created_at: 2.days.ago)
storage_move_middle = create(:project_repository_storage_move, :scheduled, created_at: 1.day.ago) storage_move_middle = create(:project_repository_storage_move, :scheduled, project: project, created_at: 1.day.ago)
get api('/project_repository_storage_moves', user) get_project_repository_storage_moves
json_ids = json_response.map {|storage_move| storage_move['id'] } json_ids = json_response.map {|storage_move| storage_move['id'] }
expect(json_ids).to eq([ expect(json_ids).to eq([
...@@ -55,35 +88,27 @@ describe API::ProjectRepositoryStorageMoves do ...@@ -55,35 +88,27 @@ describe API::ProjectRepositoryStorageMoves do
end end
end end
describe 'GET /project_repository_storage_moves/:id' do describe 'GET /project_repository_storage_moves' do
let(:project_repository_storage_move_id) { storage_move.id } it_behaves_like 'get project repository storage move list' do
let(:url) { '/project_repository_storage_moves' }
def get_project_repository_storage_move
get api("/project_repository_storage_moves/#{project_repository_storage_move_id}", user)
end end
end
it 'returns a project repository storage move' do describe 'GET /project_repository_storage_moves/:repository_storage_move_id' do
get_project_repository_storage_move it_behaves_like 'get single project repository storage move' do
let(:url) { "/project_repository_storage_moves/#{project_repository_storage_move_id}" }
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/project_repository_storage_move')
expect(json_response['id']).to eq(storage_move.id)
expect(json_response['state']).to eq(storage_move.human_state_name)
end end
end
context 'non-existent project repository storage move' do describe 'GET /projects/:id/repository_storage_moves' do
let(:project_repository_storage_move_id) { non_existing_record_id } it_behaves_like 'get project repository storage move list' do
let(:url) { "/projects/#{project.id}/repository_storage_moves" }
it 'returns not found' do
get_project_repository_storage_move
expect(response).to have_gitlab_http_status(:not_found)
end
end end
end
describe 'permissions' do describe 'GET /projects/:id/repository_storage_moves/:repository_storage_move_id' do
it { expect { get_project_repository_storage_move }.to be_allowed_for(:admin) } it_behaves_like 'get single project repository storage move' do
it { expect { get_project_repository_storage_move }.to be_denied_for(:user) } let(:url) { "/projects/#{project.id}/repository_storage_moves/#{project_repository_storage_move_id}" }
end end
end end
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