From e6f816f9faad692eece9b4aa779bd993f91786f1 Mon Sep 17 00:00:00 2001 From: d-m-u Date: Thu, 12 Jul 2018 12:59:49 -0400 Subject: [PATCH] Start of adding rake task for cb exports --- lib/task_helpers/exports/custom_buttons.rb | 56 +++++++++++++ lib/tasks/evm_export_import.rake | 8 ++ .../exports/custom_buttons_spec.rb | 80 +++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 lib/task_helpers/exports/custom_buttons.rb create mode 100644 spec/lib/task_helpers/exports/custom_buttons_spec.rb diff --git a/lib/task_helpers/exports/custom_buttons.rb b/lib/task_helpers/exports/custom_buttons.rb new file mode 100644 index 00000000000..de8e1f71807 --- /dev/null +++ b/lib/task_helpers/exports/custom_buttons.rb @@ -0,0 +1,56 @@ +module TaskHelpers + class Exports + class CustomButtons + class ExportArInstances + EXCLUDE_ATTRS = %w(id created_on updated_on created_at updated_at dialog_id resource_id).freeze + def self.export_object(obj, hash) + class_name = obj.class.name.underscore + + $log.send(:info, "Exporting #{obj.class.name} [#{obj.try('name')}] with ID: #{obj&.id}") + (hash[class_name] ||= []) << item = { 'attributes' => build_attr_list(obj.try(:attributes)) } + create_association_list(obj, item) + descendant_list(obj, item) + end + + def self.build_attr_list(attrs) + attrs&.except(*EXCLUDE_ATTRS) + end + + def self.create_association_list(obj, item) + associations = obj.class.try(:reflections) + if associations + associations = associations.collect { |model, assoc| { model => assoc.class.to_s.demodulize } }.select { |as| as.values.first != "BelongsToReflection" && as.keys.first != "all_relationships" } + associations.each do |assoc| + assoc.each do |a| + next if obj.try(a.first.to_sym).blank? + export_object(obj.try(a.first.to_sym), (item['associations'] ||= {})) + end + end + end + end + + def self.descendant_list(obj, item) + obj.try(:children)&.each { |c| export_object(c, (item['children'] ||= {})) } + end + end + + def export(options = {}) + parent_id_list = [] + objects = CustomButton.where.not(:applies_to_class => %w(ServiceTemplate GenericObject)) + + export = objects.each_with_object({}) do |obj, export_hash| + if obj.try(:parent).present? + next if parent_id_list.include?(obj.parent.id) + ExportArInstances.export_object(obj.parent, export_hash) + parent_id_list << obj.parent.id + else + ExportArInstances.export_object(obj, export_hash) + end + end + + export_dir = options[:directory] + File.write("#{export_dir}/CustomButtons.yaml", YAML.dump(export)) + end + end + end +end diff --git a/lib/tasks/evm_export_import.rake b/lib/tasks/evm_export_import.rake index 3c55988b13d..eef077f0ca1 100644 --- a/lib/tasks/evm_export_import.rake +++ b/lib/tasks/evm_export_import.rake @@ -68,6 +68,14 @@ namespace :evm do exit # exit so that parameters to the first rake task are not run as rake tasks end + + desc 'Exports all custom buttons to a single YAML file' + task :custom_buttons => :environment do + options = TaskHelpers::Exports.parse_options + TaskHelpers::Exports::CustomButtons.new.export(options) + + exit # exit so that parameters to the first rake task are not run as rake tasks + end end namespace :import do diff --git a/spec/lib/task_helpers/exports/custom_buttons_spec.rb b/spec/lib/task_helpers/exports/custom_buttons_spec.rb new file mode 100644 index 00000000000..5fc8afb0b1f --- /dev/null +++ b/spec/lib/task_helpers/exports/custom_buttons_spec.rb @@ -0,0 +1,80 @@ +describe TaskHelpers::Exports::CustomButtons do + let!(:custom_button) { FactoryGirl.create(:custom_button, :name => "export_test_button", :description => "Export Test", :applies_to_class => "Vm") } + let!(:custom_button2) { FactoryGirl.create(:custom_button, :name => "export_test_button2", :description => "Export Test", :applies_to_class => "Service") } + let!(:custom_button_set) { FactoryGirl.create(:custom_button_set, :name => "custom_button_set", :description => "Default Export Test") } + let(:export_dir) { Dir.mktmpdir('miq_exp_dir') } + + let(:custom_button_export_test) do + {"custom_button_set" => [{ + "attributes" => { + "name" => "custom_button_set", + "description" => "Default Export Test", + "set_type" => "CustomButtonSet", + "guid" => custom_button_set.guid, + "read_only" => nil, + "set_data" => nil, + "mode" => nil, + "owner_type" => nil, + "owner_id" => nil, + "userid" => nil, + "group_id" => nil + }, + "children" => { + "custom_button" => [{ + "attributes" => { + "guid" => custom_button.guid, + "description" => "Export Test", + "applies_to_class" => "Vm", + "visibility_expression" => nil, + "options" => nil, + "userid" => nil, + "wait_for_complete" => nil, + "name" => "export_test_button", + "visibility" => nil, + "applies_to_id" => nil, + "enablement_expression" => nil, + "disabled_text" => nil + } + }] + } + }], + "custom_button" => [{ + "attributes" => { + "guid" => custom_button2.guid, + "description" => "Export Test", + "applies_to_class" => "Service", + "visibility_expression" => nil, + "options" => nil, + "userid" => nil, + "wait_for_complete" => nil, + "name" => "export_test_button2", + "visibility" => nil, + "applies_to_id" => nil, + "enablement_expression" => nil, + "disabled_text" => nil + } + }]} + end + + before do + custom_button_set.add_member(custom_button) + end + + after do + FileUtils.remove_entry export_dir + end + + it 'exports custom buttons to a given directory' do + TaskHelpers::Exports::CustomButtons.new.export(:directory => export_dir) + file_contents = File.read("#{export_dir}/CustomButtons.yaml") + expect(YAML.safe_load(file_contents)).to contain_exactly(*custom_button_export_test) + expect(Dir[File.join(export_dir, '**', '*')].count { |file| File.file?(file) }).to eq(1) + end + + it 'exports all custom buttons to a given directory' do + TaskHelpers::Exports::CustomButtons.new.export(:directory => export_dir, :all => true) + file_contents = File.read("#{export_dir}/CustomButtons.yaml") + expect(YAML.safe_load(file_contents)).to contain_exactly(*custom_button_export_test) + expect(Dir[File.join(export_dir, '**', '*')].count { |file| File.file?(file) }).to eq(1) + end +end