# # Copyright (c) 2014 Constant Contact # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # module JenkinsPipelineBuilder class View # Initializes a new View object. # # @param generator [Generator] the client object # # @return [View] the view object # def initialize(generator) @generator = generator @client = generator.client @logger = @client.logger end def generate(path) hash = if path.end_with? 'json' JSON.parse(IO.read(path)) else YAML.load_file(path) end hash.each do |item| Utils.symbolize_keys_deep!(item) create(item[:view]) if item[:view] end end # Creates a listview by accepting the given parameters hash # # @param [Hash] params options to create the new view # @option params [String] :name Name of the view # @option params [String] :type Description of the view # @option params [String] :description Description of the view # @option params [String] :status_filter Filter jobs based on the status. # Valid options: all_selected_jobs, enabled_jobs_only, # disabled_jobs_only. Default: all_selected_jobs # @option params [Boolean] :filter_queue true or false # @option params [Boolean] :filter_executors true or false # @option params [String] :regex Regular expression to filter jobs that # are to be added to the view # # @raise [ArgumentError] if the required parameter +:name+ is not # specified # def create(params) # Name is a required parameter. Raise an error if not specified raise ArgumentError, 'Name is required for creating view' unless params.is_a?(Hash) && params[:name] clean_up_views(params) unless JenkinsPipelineBuilder.debug params[:type] ||= 'listview' create_base_view(params[:name], params[:type], params[:parent_view]) @logger.debug "Creating a #{params[:type]} view with params: #{params.inspect}" return if JenkinsPipelineBuilder.debug view_path = params[:parent_view].nil? ? '' : "/view/#{params[:parent_view]}" view_path += "/view/#{params[:name]}/configSubmit" @client.api_post_request(view_path, post_params(params)) end private def clean_up_views(params) # If we have a parent view, we need to do some additional checks if params[:parent_view] create_base_view(params[:parent_view], 'nestedView') unless exists?(params[:parent_view]) delete(params[:name], params[:parent_view]) if exists?(params[:name], params[:parent_view]) elsif exists?(params[:name]) delete(params[:name]) end end def post_params(params) payload = post_payload params payload['filterQueue'] = 'on' if params[:filter_queue] payload['filterExecutors'] = 'on' if params[:filter_executors] if params[:regex] payload['useincluderegex'] = 'on' payload['includeRegex'] = params[:regex] end payload end def post_payload(params) statuses = { 'enabled_jobs_only' => '1', 'disabled_jobs_only' => '2' } json = { 'name' => params[:name], 'description' => params[:description], 'mode' => get_mode(params[:type]), 'statusFilter' => '', 'columns' => get_columns(params[:type]) } json['groupingRules'] = params[:groupingRules] if params[:groupingRules] { 'name' => params[:name], 'mode' => get_mode(params[:type]), 'description' => params[:description], 'statusFilter' => statuses.fetch(params[:status_filter], ''), 'json' => json.to_json } end def get_mode(type) types = { 'listview' => 'hudson.model.ListView', 'myview' => 'hudson.model.MyView', 'nestedView' => 'hudson.plugins.nested_view.NestedView', 'categorizedView' => 'org.jenkinsci.plugins.categorizedview.CategorizedJobsView', 'dashboardView' => 'hudson.plugins.view.dashboard.Dashboard', 'multijobView' => 'com.tikal.jenkins.plugins.multijob.views.MultiJobView' } raise "Type #{type} is not supported by Jenkins." unless types.key?(type) types[type] end # Creates a new empty view of the given type # # @param [String] view_name Name of the view to be created # @param [String] type Type of view to be created. Valid options: # listview, myview. Default: listview # def create_base_view(view_name, type = 'listview', parent_view_name = nil) @logger.info "Creating a view '#{view_name}' of type '#{type}'" mode = get_mode(type) initial_post_params = { 'name' => view_name, 'mode' => mode, 'json' => { 'name' => view_name, 'mode' => mode }.to_json } if JenkinsPipelineBuilder.debug # pp initial_post_params return end view_path = parent_view_name.nil? ? '' : "/view/#{parent_view_name}" view_path += '/createView' @client.api_post_request(view_path, initial_post_params) end def get_columns(type) column_names = ['Status', 'Weather', 'Last Success', 'Last Failure', 'Last Duration', 'Build Button'] if type == 'categorizedView' column_names.insert(2, 'Categorized - Job') else column_names.insert(2, 'Name') end result = [] column_names.each do |name| result << columns_repository[name] end result end def columns_repository { 'Status' => { 'stapler-class' => 'hudson.views.StatusColumn', 'kind' => 'hudson.views.StatusColumn' }, 'Weather' => { 'stapler-class' => 'hudson.views.WeatherColumn', 'kind' => 'hudson.views.WeatherColumn' }, 'Name' => { 'stapler-class' => 'hudson.views.JobColumn', 'kind' => 'hudson.views.JobColumn' }, 'Last Success' => { 'stapler-class' => 'hudson.views.LastSuccessColumn', 'kind' => 'hudson.views.LastSuccessColumn' }, 'Last Failure' => { 'stapler-class' => 'hudson.views.LastFailureColumn', 'kind' => 'hudson.views.LastFailureColumn' }, 'Last Duration' => { 'stapler-class' => 'hudson.views.LastDurationColumn', 'kind' => 'hudson.views.LastDurationColumn' }, 'Build Button' => { 'stapler-class' => 'hudson.views.BuildButtonColumn', 'kind' => 'hudson.views.BuildButtonColumn' }, 'Categorized - Job' => { 'stapler-class' => 'org.jenkinsci.plugins.categorizedview.IndentedJobColumn', 'kind' => 'org.jenkinsci.plugins.categorizedview.IndentedJobColumn' } } end # This method lists all views # # @param [String] parent_view a name of the parent view # @param [String] filter a regex to filter view names # @param [Bool] ignorecase whether to be case sensitive or not # def list_children(parent_view = nil, filter = '', ignorecase = true) @logger.info "Obtaining children views of parent #{parent_view} based on filter '#{filter}'" view_names = [] path = parent_view.nil? ? '' : "/view/#{parent_view}" response_json = @client.api_get_request(path) response_json['views'].each do |view| filter_exp = ignorecase ? /#{filter}/i : /#{filter}/ view_names << view['name'] if view['name'] =~ filter_exp end view_names end # Delete a view # # @param [String] view_name # def delete(view_name, parent_view = nil) @logger.info "Deleting view '#{view_name}'" path = parent_view.nil? ? '' : "/view/#{parent_view}" path += "/view/#{view_name}/doDelete" @client.api_post_request(path) end # Checks if the given view exists in Jenkins # # @param [String] view_name # def exists?(view_name, parent_view = nil) if parent_view list_children(parent_view, view_name).include?(view_name) else @client.view.list(view_name).include?(view_name) end end end end