Skip to content

Commit

Permalink
Merge pull request #17726 from d-m-u/custom_button_import
Browse files Browse the repository at this point in the history
Add rake task to import custom buttons
  • Loading branch information
gmcculloug authored Aug 2, 2018
2 parents 12bfb59 + e2d1697 commit 4f8556c
Show file tree
Hide file tree
Showing 5 changed files with 346 additions and 0 deletions.
80 changes: 80 additions & 0 deletions lib/task_helpers/imports/custom_buttons.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
module TaskHelpers
class Imports
class CustomButtons
def import(options)
return unless options[:source]
glob = File.file?(options[:source]) ? options[:source] : "#{options[:source]}/*.yaml"
Dir.glob(glob) do |filename|
begin
import_custom_buttons(filename)
rescue StandardError
raise StandardError, "Error importing #{filename} at #{$@}"
end
end
end

private

class ImportArInstances
def self.import(obj_hash)
new.import(obj_hash)
end

def import(obj_hash)
ActiveRecord::Base.transaction { obj_hash.each { |obj_def| create_object(*obj_def) } }
end

def create_object(class_name, obj_array)
klass = class_name.camelize.constantize

obj_array.collect do |obj|
begin
klass.create!(obj['attributes']&.except('guid')).tap do |new_obj|
add_children(obj, new_obj)
add_associations(obj, new_obj)
try("#{class_name}_post", new_obj)
end
rescue StandardError
raise
end
end
end

def add_children(obj, new_obj)
if obj['children'].present?
obj['children'].each do |child|
new_obj.add_members(create_object(*child))
end
end
end

def add_associations(obj, new_obj)
if obj['associations'].present?
obj['associations'].each do |assoc|
new_obj.send("#{assoc.first}=", create_object(*assoc).first)
end
end
end

def custom_button_set_post(new_obj)
new_obj.set_data[:button_order] = new_obj.custom_buttons.collect(&:id)
new_obj.save!
end

def custom_button_post(new_obj)
check_user(new_obj)
end

def check_user(new_obj)
existing_user = User.find_by(:name => new_obj[:userid])
new_obj.update_attributes(:userid => existing_user.nil? ? "admin" : existing_user)
end
end

def import_custom_buttons(filename)
custom_buttons = YAML.load_file(filename)
ImportArInstances.import(custom_buttons)
end
end
end
end
8 changes: 8 additions & 0 deletions lib/tasks/evm_export_import.rake
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,13 @@ namespace :evm do

exit # exit so that parameters to the first rake task are not run as rake tasks
end

desc 'Imports all custom buttons from YAML file'
task :custom_buttons => :environment do
options = TaskHelpers::Imports.parse_options
TaskHelpers::Imports::CustomButtons.new.import(options)

exit # exit so that parameters to the first rake task are not run as rake tasks
end
end
end
89 changes: 89 additions & 0 deletions spec/lib/task_helpers/imports/custom_buttons_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
describe TaskHelpers::Imports::CustomButtons do
let(:data_dir) { File.join(File.expand_path(__dir__), 'data', 'custom_buttons') }
let(:custom_button_file) { 'CustomButtons.yaml' }
let(:bad_custom_button_file) { 'CustomButtonsBad.yaml' }
let(:custom_button_set_name) { 'group1|Vm|' }
let(:custom_button_set_description) { 'group1' }
let(:resource_action_ae_namespace) { 'SYSTEM' }
let(:options) { {:source => source} }

describe "#import" do
describe "when the source is a directory" do
let(:source) { data_dir }

context "without existing buttons" do
it 'imports all formatted .yaml files in a specified directory' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_test_custom_button_set_present
end
end

context "with existing identical buttons" do
it 'should raise' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_raises_import_error
end
end

context "yaml import failure" do
it 'should raise' do
file = Tempfile.new('foo.yaml', data_dir)
file.write("bad yaml here")
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_raises_import_error
assert_imports_only_custom_button_set_one
end
end
end

describe "when the source is a file" do
let(:source) { "#{data_dir}/#{custom_button_file}" }

context "without existing buttons" do
context "only imports good yaml" do
it 'imports a specified file' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_test_custom_button_set_present
assert_imports_only_custom_button_set_one
end
end

context "doesn't import bad yaml" do
let(:source) { "#{data_dir}/#{bad_custom_button_file}" }
it 'does not imports a specified file' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_imports_no_custom_buttons
end
end
end

context "with existing identical buttons" do
it 'should not import anything' do
TaskHelpers::Imports::CustomButtons.new.import(options)
assert_raises_import_error
assert_imports_only_custom_button_set_one
end
end
end
end

def assert_test_custom_button_set_present
cbs = CustomButtonSet.find_by(:name => custom_button_set_name)
expect(cbs.custom_buttons.count).to eq(3)
expect(cbs.description).to eq(custom_button_set_description)
expect(cbs.custom_buttons.first.resource_action.ae_namespace).to eq(resource_action_ae_namespace)
expect(cbs.custom_buttons.pluck(:userid)).to eq(%w(admin admin admin))
end

def assert_imports_only_custom_button_set_one
expect(CustomButton.count).to eq(3)
end

def assert_imports_no_custom_buttons
expect(CustomButton.count).to eq(0)
end

def assert_raises_import_error
expect { TaskHelpers::Imports::CustomButtons.new.import(options) }.to raise_error(StandardError, /Error importing/)
end
end
134 changes: 134 additions & 0 deletions spec/lib/task_helpers/imports/data/custom_buttons/CustomButtons.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
custom_button_set:
- attributes:
name: group1|Vm|
description: group1
set_type: CustomButtonSet
guid: ba4ff235-75eb-4fa4-a9f9-b854d4186c3a
read_only:
set_data:
:button_order:
- 2
- 3
- 10
:button_icon: ff ff-class
:button_color: "#a341ab"
:display: true
:applies_to_class: Vm
:group_index: 1
mode:
owner_type:
owner_id:
userid:
group_id:
children:
custom_button:
- attributes:
guid: f059931f-8703-4bcf-b876-e482d38ce8ea
description: button 1
applies_to_class: Vm
visibility_expression:
options:
:button_icon: pficon pficon-cpu
:button_type: default
:display: true
:open_url: false
:display_for: single
:submit_how: one
userid: admin
wait_for_complete:
name: button 1
visibility:
:roles:
- _ALL_
applies_to_id:
enablement_expression:
disabled_text:
associations:
resource_action:
- attributes:
action:
resource_type: CustomButton
ae_namespace: SYSTEM
ae_class: PROCESS
ae_instance: Request
ae_message:
ae_attributes:
request: test1
configuration_template_id:
configuration_template_type:
- attributes:
guid: 3f50d617-851e-451f-95ae-a17fc548cb11
description: button 2
applies_to_class: Vm
visibility_expression:
options:
:button_icon: pficon pficon-home
:button_color: "#c03638"
:button_type: default
:display: true
:open_url: false
:display_for: single
:submit_how: one
userid:
wait_for_complete:
name: button 2
visibility:
:roles:
- _ALL_
applies_to_id:
enablement_expression:
disabled_text:
associations:
resource_action:
- attributes:
action:
resource_type: CustomButton
ae_namespace: SYSTEM
ae_class: PROCESS
ae_instance: Request
ae_message:
ae_attributes:
request: test2
configuration_template_id:
configuration_template_type:
- attributes:
guid: d3cd608a-f476-48b7-aa25-a930ec046e00
description: multiselect
applies_to_class: Vm
visibility_expression: !ruby/object:MiqExpression
exp:
"=":
field: Vm-power_state
value: 'on'
context_type:
options:
:button_icon: fa fa-users
:button_color: "#996633"
:button_type: default
:display: true
:open_url: false
:display_for: both
:submit_how: all
userid: admin
wait_for_complete:
name: multiselect
visibility:
:roles:
- _ALL_
applies_to_id:
enablement_expression:
disabled_text:
associations:
resource_action:
- attributes:
action:
resource_type: CustomButton
ae_namespace: SYSTEM
ae_class: PROCESS
ae_instance: Request
ae_message:
ae_attributes:
request: multiselect
configuration_template_id:
configuration_template_type:
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
custom_button:
- attributes:
guid: f059931f-8703-4bcf-b876-e482d38ce8ea
description: button 1
applies_to_class: Vm
visibility_expression:
options:
:button_icon: pficon pficon-cpu
:button_type: default
:display: true
:open_url: false
:display_for: single
:submit_how: one
userid: admin
wait_for_complete:
name: button 1
visibility:
:roles:
- _ALL_
applies_to_id:
enablement_expression:
disabled_text:
associations:
resource_action:
- attributes:
action:
resource_type: CustomButton
ae_namespace: SYSTEM
ae_class: PROCESS
ae_instance: Request
ae_message:
ae_attributes:
request: test1
configuration_template_id:
configuration_template_type:

0 comments on commit 4f8556c

Please sign in to comment.