diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 15:26:25 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-07-20 15:26:25 +0300 |
commit | a09983ae35713f5a2bbb100981116d31ce99826e (patch) | |
tree | 2ee2af7bd104d57086db360a7e6d8c9d5d43667a /app/services/terraform | |
parent | 18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff) |
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'app/services/terraform')
-rw-r--r-- | app/services/terraform/remote_state_handler.rb | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/app/services/terraform/remote_state_handler.rb b/app/services/terraform/remote_state_handler.rb index d180a3a2432..d2c44d4a265 100644 --- a/app/services/terraform/remote_state_handler.rb +++ b/app/services/terraform/remote_state_handler.rb @@ -5,26 +5,17 @@ module Terraform include Gitlab::OptimisticLocking StateLockedError = Class.new(StandardError) + UnauthorizedError = Class.new(StandardError) - # rubocop: disable CodeReuse/ActiveRecord def find_with_lock - raise ArgumentError unless params[:name].present? - - state = Terraform::State.find_by(project: project, name: params[:name]) - raise ActiveRecord::RecordNotFound.new("Couldn't find state") unless state - - retry_optimistic_lock(state) { |state| yield state } if state && block_given? - state - end - # rubocop: enable CodeReuse/ActiveRecord - - def create_or_find! - raise ArgumentError unless params[:name].present? - - Terraform::State.create_or_find_by(project: project, name: params[:name]) + retrieve_with_lock(find_only: true) do |state| + yield state if block_given? + end end def handle_with_lock + raise UnauthorizedError unless can_modify_state? + retrieve_with_lock do |state| raise StateLockedError unless lock_matches?(state) @@ -36,6 +27,7 @@ module Terraform def lock! raise ArgumentError if params[:lock_id].blank? + raise UnauthorizedError unless can_modify_state? retrieve_with_lock do |state| raise StateLockedError if state.locked? @@ -49,6 +41,8 @@ module Terraform end def unlock! + raise UnauthorizedError unless can_modify_state? + retrieve_with_lock do |state| # force-unlock does not pass ID, so we ignore it if it is missing raise StateLockedError unless params[:lock_id].nil? || lock_matches?(state) @@ -63,8 +57,21 @@ module Terraform private - def retrieve_with_lock - create_or_find!.tap { |state| retry_optimistic_lock(state) { |state| yield state } } + def retrieve_with_lock(find_only: false) + create_or_find!(find_only: find_only).tap { |state| retry_optimistic_lock(state) { |state| yield state } } + end + + def create_or_find!(find_only:) + raise ArgumentError unless params[:name].present? + + find_params = { project: project, name: params[:name] } + + if find_only + Terraform::State.find_by(find_params) || # rubocop: disable CodeReuse/ActiveRecord + raise(ActiveRecord::RecordNotFound.new("Couldn't find state")) + else + Terraform::State.create_or_find_by(find_params) + end end def lock_matches?(state) @@ -73,5 +80,9 @@ module Terraform ActiveSupport::SecurityUtils .secure_compare(state.lock_xid.to_s, params[:lock_id].to_s) end + + def can_modify_state? + current_user.can?(:admin_terraform_state, project) + end end end |