summaryrefslogtreecommitdiff
path: root/lib/api/terraform/state.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api/terraform/state.rb')
-rw-r--r--lib/api/terraform/state.rb29
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/api/terraform/state.rb b/lib/api/terraform/state.rb
index 577d011ebad..bdc9f975970 100644
--- a/lib/api/terraform/state.rb
+++ b/lib/api/terraform/state.rb
@@ -20,6 +20,8 @@ module API
render_api_error!(e.message, 422)
end
+ STATE_NAME_URI_REQUIREMENTS = { name: API::NO_SLASH_URL_PART_REGEX }.freeze
+
before do
authenticate!
authorize! :read_terraform_state, user_project
@@ -45,7 +47,7 @@ module API
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
- namespace ':id/terraform/state/:name' do
+ namespace ':id/terraform/state/:name', requirements: STATE_NAME_URI_REQUIREMENTS do
params do
requires :name, type: String, desc: 'The name of a Terraform state'
optional :ID, type: String, limit: 255, desc: 'Terraform state lock ID'
@@ -55,6 +57,17 @@ module API
def remote_state_handler
::Terraform::RemoteStateHandler.new(user_project, current_user, name: params[:name], lock_id: params[:ID])
end
+
+ def not_found_for_dots?
+ Feature.disabled?(:allow_dots_on_tf_state_names) && params[:name].include?(".")
+ end
+
+ # Change the state name to behave like before, https://gitlab.com/gitlab-org/gitlab/-/merge_requests/105674
+ # has been introduced. This behavior can be controlled via `allow_dots_on_tf_state_names` FF.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106861
+ def legacy_state_name!
+ params[:name] = params[:name].split('.').first
+ end
end
desc 'Get a Terraform state by its name' do
@@ -72,6 +85,8 @@ module API
end
route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
get do
+ legacy_state_name! if not_found_for_dots?
+
remote_state_handler.find_with_lock do |state|
no_content! unless state.latest_file && state.latest_file.exists?
@@ -88,17 +103,22 @@ module API
]
failure [
{ code: 403, message: 'Forbidden' },
- { code: 422, message: 'Validation failure' }
+ { code: 422, message: 'Validation failure' },
+ { code: 413, message: 'Request Entity Too Large' }
]
tags %w[terraform_state]
end
route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
post do
authorize! :admin_terraform_state, user_project
+ legacy_state_name! if not_found_for_dots?
data = request.body.read
no_content! if data.empty?
+ max_state_size = Gitlab::CurrentSettings.max_terraform_state_size_bytes
+ file_too_large! if max_state_size > 0 && data.size > max_state_size
+
remote_state_handler.handle_with_lock do |state|
state.update_file!(CarrierWaveStringFile.new(data), version: params[:serial], build: current_authenticated_job)
end
@@ -120,6 +140,7 @@ module API
route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth
delete do
authorize! :admin_terraform_state, user_project
+ legacy_state_name! if not_found_for_dots?
remote_state_handler.find_with_lock do |state|
::Terraform::States::TriggerDestroyService.new(state, current_user: current_user).execute
@@ -151,6 +172,8 @@ module API
requires :Path, type: String, desc: 'Terraform path'
end
post '/lock' do
+ not_found! if not_found_for_dots?
+
authorize! :admin_terraform_state, user_project
status_code = :ok
@@ -194,6 +217,8 @@ module API
optional :ID, type: String, limit: 255, desc: 'Terraform state lock ID'
end
delete '/lock' do
+ not_found! if not_found_for_dots?
+
authorize! :admin_terraform_state, user_project
remote_state_handler.unlock!