1# frozen_string_literal: true 2 3module API 4 module Terraform 5 class StateVersion < ::API::Base 6 default_format :json 7 8 feature_category :infrastructure_as_code 9 10 before do 11 authenticate! 12 authorize! :read_terraform_state, user_project 13 end 14 15 params do 16 requires :id, type: String, desc: 'The ID of a project' 17 end 18 19 resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do 20 namespace ':id/terraform/state/:name/versions/:serial' do 21 params do 22 requires :name, type: String, desc: 'The name of a Terraform state' 23 requires :serial, type: Integer, desc: 'The version number of the state' 24 end 25 26 helpers do 27 def remote_state_handler 28 ::Terraform::RemoteStateHandler.new(user_project, current_user, name: params[:name]) 29 end 30 31 def find_version(serial) 32 remote_state_handler.find_with_lock do |state| 33 version = state.versions.find_by_version(serial) 34 35 if version.present? 36 yield version 37 else 38 not_found! 39 end 40 end 41 end 42 end 43 44 desc 'Get a terraform state version' 45 route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth 46 get do 47 find_version(params[:serial]) do |version| 48 env['api.format'] = :binary # Bypass json serialization 49 body version.file.read 50 status :ok 51 end 52 end 53 54 desc 'Delete a terraform state version' 55 route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth 56 delete do 57 authorize! :admin_terraform_state, user_project 58 59 find_version(params[:serial]) do |version| 60 version.destroy! 61 62 body false 63 status :no_content 64 end 65 end 66 end 67 end 68 end 69 end 70end 71