2020-02-26 10:08:56 -05:00
# frozen_string_literal: true
# Updates the content of a specified dashboard in .yml file inside `.gitlab/dashboards`
module Metrics
module Dashboard
class UpdateDashboardService < :: BaseService
2020-03-17 17:09:16 -04:00
include Stepable
2020-02-26 10:08:56 -05:00
ALLOWED_FILE_TYPE = '.yml'
2020-03-23 11:09:36 -04:00
USER_DASHBOARDS_DIR = :: Metrics :: Dashboard :: CustomDashboardService :: DASHBOARD_ROOT
2020-02-26 10:08:56 -05:00
2020-03-17 17:09:16 -04:00
steps :check_push_authorized ,
:check_branch_name ,
:check_file_type ,
2020-03-23 08:09:47 -04:00
:update_file ,
:create_merge_request
2020-02-26 10:08:56 -05:00
2020-03-17 17:09:16 -04:00
def execute
execute_steps
2020-02-26 10:08:56 -05:00
end
private
2020-03-17 17:09:16 -04:00
def check_push_authorized ( result )
return error ( _ ( 'You are not allowed to push into this branch. Create another branch or open a merge request.' ) , :forbidden ) unless push_authorized?
success ( result )
2020-02-26 10:08:56 -05:00
end
2020-03-17 17:09:16 -04:00
def check_branch_name ( result )
return error ( _ ( 'There was an error updating the dashboard, branch name is invalid.' ) , :bad_request ) unless valid_branch_name?
return error ( _ ( 'There was an error updating the dashboard, branch named: %{branch} already exists.' ) % { branch : params [ :branch ] } , :bad_request ) unless new_or_default_branch?
success ( result )
2020-02-26 10:08:56 -05:00
end
2020-03-17 17:09:16 -04:00
def check_file_type ( result )
return error ( _ ( 'The file name should have a .yml extension' ) , :bad_request ) unless target_file_type_valid?
success ( result )
2020-02-26 10:08:56 -05:00
end
2020-03-17 17:09:16 -04:00
def update_file ( result )
file_update_response = :: Files :: UpdateService . new ( project , current_user , dashboard_attrs ) . execute
2020-02-26 10:08:56 -05:00
2020-03-17 17:09:16 -04:00
if file_update_response [ :status ] == :success
success ( result . merge ( file_update_response , http_status : :created , dashboard : dashboard_details ) )
else
error ( file_update_response [ :message ] , :bad_request )
2020-02-26 10:08:56 -05:00
end
end
2020-03-23 08:09:47 -04:00
def create_merge_request ( result )
return success ( result ) if project . default_branch == branch
merge_request_params = {
source_branch : branch ,
target_branch : project . default_branch ,
title : params [ :commit_message ]
}
merge_request = :: MergeRequests :: CreateService . new ( project , current_user , merge_request_params ) . execute
if merge_request . persisted?
success ( result . merge ( merge_request : Gitlab :: UrlBuilder . build ( merge_request ) ) )
else
error ( merge_request . errors . full_messages . join ( ',' ) , :bad_request )
end
end
2020-03-17 17:09:16 -04:00
def push_authorized?
Gitlab :: UserAccess . new ( current_user , project : project ) . can_push_to_branch? ( branch )
2020-02-26 10:08:56 -05:00
end
def valid_branch_name?
2020-03-17 17:09:16 -04:00
Gitlab :: GitRefValidator . validate ( branch )
2020-02-26 10:08:56 -05:00
end
2020-03-17 17:09:16 -04:00
def new_or_default_branch?
! repository . branch_exists? ( branch ) || project . default_branch == branch
2020-02-26 10:08:56 -05:00
end
def target_file_type_valid?
File . extname ( params [ :file_name ] ) == ALLOWED_FILE_TYPE
end
2020-03-17 17:09:16 -04:00
def dashboard_attrs
{
commit_message : params [ :commit_message ] ,
file_path : update_dashboard_path ,
file_content : update_dashboard_content ,
encoding : 'text' ,
branch_name : branch ,
start_branch : repository . branch_exists? ( branch ) ? branch : project . default_branch
}
end
def update_dashboard_path
File . join ( USER_DASHBOARDS_DIR , file_name )
end
2020-02-26 10:08:56 -05:00
def file_name
2020-03-17 17:09:16 -04:00
@file_name || = File . basename ( CGI . unescape ( params [ :file_name ] ) )
end
2020-02-26 10:08:56 -05:00
2020-03-17 17:09:16 -04:00
def branch
@branch || = params [ :branch ]
2020-02-26 10:08:56 -05:00
end
def update_dashboard_content
:: PerformanceMonitoring :: PrometheusDashboard . from_json ( params [ :file_content ] ) . to_yaml
end
def repository
@repository || = project . repository
end
2020-03-17 17:09:16 -04:00
def dashboard_details
{
path : update_dashboard_path ,
2020-03-23 11:09:36 -04:00
display_name : :: Metrics :: Dashboard :: CustomDashboardService . name_for_path ( update_dashboard_path ) ,
2020-03-17 17:09:16 -04:00
default : false ,
system_dashboard : false
}
end
2020-02-26 10:08:56 -05:00
end
end
end