Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/terraform/state_spec.rb')
-rw-r--r--spec/requests/api/terraform/state_spec.rb238
1 files changed, 187 insertions, 51 deletions
diff --git a/spec/requests/api/terraform/state_spec.rb b/spec/requests/api/terraform/state_spec.rb
index b0a963db684..88c277f4e08 100644
--- a/spec/requests/api/terraform/state_spec.rb
+++ b/spec/requests/api/terraform/state_spec.rb
@@ -3,95 +3,231 @@
require 'spec_helper'
describe API::Terraform::State do
- def auth_header_for(user)
- auth_header = ActionController::HttpAuthentication::Basic.encode_credentials(
- user.username,
- create(:personal_access_token, user: user).token
- )
- { 'HTTP_AUTHORIZATION' => auth_header }
- end
+ let_it_be(:project) { create(:project) }
+ let_it_be(:developer) { create(:user, developer_projects: [project]) }
+ let_it_be(:maintainer) { create(:user, maintainer_projects: [project]) }
+
+ let!(:state) { create(:terraform_state, :with_file, project: project) }
- let!(:project) { create(:project) }
- let(:developer) { create(:user) }
- let(:maintainer) { create(:user) }
- let(:state_name) { 'state' }
+ let(:current_user) { maintainer }
+ let(:auth_header) { basic_auth_header(current_user) }
+ let(:project_id) { project.id }
+ let(:state_name) { state.name }
+ let(:state_path) { "/projects/#{project_id}/terraform/state/#{state_name}" }
before do
- project.add_maintainer(maintainer)
+ stub_terraform_state_object_storage(Terraform::StateUploader)
end
describe 'GET /projects/:id/terraform/state/:name' do
- it 'returns 401 if user is not authenticated' do
- headers = { 'HTTP_AUTHORIZATION' => 'failing_token' }
- get api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: headers
+ subject(:request) { get api(state_path), headers: auth_header }
- expect(response).to have_gitlab_http_status(:unauthorized)
- end
+ context 'without authentication' do
+ let(:auth_header) { basic_auth_header('failing_token') }
- it 'returns terraform state belonging to a project of given state name' do
- get api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: auth_header_for(maintainer)
+ it 'returns 401 if user is not authenticated' do
+ request
- expect(response).to have_gitlab_http_status(:not_implemented)
- expect(response.body).to eq('not implemented')
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
end
- it 'returns not found if the project does not exists' do
- get api("/projects/0000/terraform/state/#{state_name}"), headers: auth_header_for(maintainer)
+ context 'with maintainer permissions' do
+ let(:current_user) { maintainer }
+
+ it 'returns terraform state belonging to a project of given state name' do
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to eq(state.file.read)
+ end
+
+ context 'for a project that does not exist' do
+ let(:project_id) { '0000' }
+
+ it 'returns not found' do
+ request
- expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
- it 'returns forbidden if the user cannot access the state' do
- project.add_developer(developer)
- get api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: auth_header_for(developer)
+ context 'with developer permissions' do
+ let(:current_user) { developer }
+
+ it 'returns forbidden if the user cannot access the state' do
+ request
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
end
end
describe 'POST /projects/:id/terraform/state/:name' do
+ let(:params) { { 'instance': 'example-instance' } }
+
+ subject(:request) { post api(state_path), headers: auth_header, as: :json, params: params }
+
context 'when terraform state with a given name is already present' do
- it 'updates the state' do
- post api("/projects/#{project.id}/terraform/state/#{state_name}"),
- params: '{ "instance": "example-instance" }',
- headers: { 'Content-Type' => 'text/plain' }.merge(auth_header_for(maintainer))
+ context 'with maintainer permissions' do
+ let(:current_user) { maintainer }
- expect(response).to have_gitlab_http_status(:not_implemented)
- expect(response.body).to eq('not implemented')
+ it 'updates the state' do
+ expect { request }.to change { Terraform::State.count }.by(0)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
- it 'returns forbidden if the user cannot access the state' do
- project.add_developer(developer)
- get api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: auth_header_for(developer)
+ context 'without body' do
+ let(:params) { nil }
- expect(response).to have_gitlab_http_status(:forbidden)
+ it 'returns no content if no body is provided' do
+ request
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+
+ context 'with developer permissions' do
+ let(:current_user) { developer }
+
+ it 'returns forbidden' do
+ request
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
end
end
context 'when there is no terraform state of a given name' do
- it 'creates a new state' do
- post api("/projects/#{project.id}/terraform/state/example2"),
- headers: auth_header_for(maintainer),
- params: '{ "database": "example-database" }'
+ let(:state_name) { 'example2' }
+
+ context 'with maintainer permissions' do
+ let(:current_user) { maintainer }
+
+ it 'creates a new state' do
+ expect { request }.to change { Terraform::State.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'without body' do
+ let(:params) { nil }
+
+ it 'returns no content if no body is provided' do
+ request
- expect(response).to have_gitlab_http_status(:not_implemented)
- expect(response.body).to eq('not implemented')
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+ end
+
+ context 'with developer permissions' do
+ let(:current_user) { developer }
+
+ it 'returns forbidden' do
+ request
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
end
end
end
describe 'DELETE /projects/:id/terraform/state/:name' do
- it 'deletes the state' do
- delete api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: auth_header_for(maintainer)
+ subject(:request) { delete api(state_path), headers: auth_header }
+
+ context 'with maintainer permissions' do
+ let(:current_user) { maintainer }
+
+ it 'deletes the state' do
+ expect { request }.to change { Terraform::State.count }.by(-1)
- expect(response).to have_gitlab_http_status(:not_implemented)
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with developer permissions' do
+ let(:current_user) { developer }
+
+ it 'returns forbidden' do
+ expect { request }.to change { Terraform::State.count }.by(0)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+ end
+
+ describe 'PUT /projects/:id/terraform/state/:name/lock' do
+ let(:params) do
+ {
+ ID: '123-456',
+ Version: '0.1',
+ Operation: 'OperationTypePlan',
+ Info: '',
+ Who: "#{current_user.username}",
+ Created: Time.now.utc.iso8601(6),
+ Path: ''
+ }
+ end
+
+ subject(:request) { post api("#{state_path}/lock"), headers: auth_header, params: params }
+
+ it 'locks the terraform state' do
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
end
+ end
+
+ describe 'DELETE /projects/:id/terraform/state/:name/lock' do
+ before do
+ state.lock_xid = '123-456'
+ state.save!
+ end
+
+ subject(:request) { delete api("#{state_path}/lock"), headers: auth_header, params: params }
- it 'returns forbidden if the user cannot access the state' do
- project.add_developer(developer)
- get api("/projects/#{project.id}/terraform/state/#{state_name}"), headers: auth_header_for(developer)
+ context 'with the correct lock id' do
+ let(:params) { { ID: '123-456' } }
- expect(response).to have_gitlab_http_status(:forbidden)
+ it 'removes the terraform state lock' do
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with no lock id (force-unlock)' do
+ let(:params) { {} }
+
+ it 'removes the terraform state lock' do
+ request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ context 'with an incorrect lock id' do
+ let(:params) { { ID: '456-789' } }
+
+ it 'returns an error' do
+ request
+
+ expect(response).to have_gitlab_http_status(:conflict)
+ end
+ end
+
+ context 'with a longer than 255 character lock id' do
+ let(:params) { { ID: '0' * 256 } }
+
+ it 'returns an error' do
+ request
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ end
end
end
end