diff --git a/app/models/dialog/ansible_playbook_service_dialog.rb b/app/models/dialog/ansible_playbook_service_dialog.rb new file mode 100644 index 00000000000..52d51ef27e6 --- /dev/null +++ b/app/models/dialog/ansible_playbook_service_dialog.rb @@ -0,0 +1,98 @@ +class Dialog + class AnsiblePlaybookServiceDialog + def self.create_dialog(label, job_template, hosts = 'localhost') + new.create_dialog(label, job_template, hosts) + end + + # This dialog is to be used by a playbook service + # The job_template contains the playbook + def create_dialog(label, job_template, hosts = 'localhost') + Dialog.new(:label => label, :buttons => "submit,cancel").tap do |dialog| + tab = dialog.dialog_tabs.build(:display => "edit", :label => "Basic Information", :position => 0) + add_options_group(tab, 0, hosts) + unless job_template.variables.blank? + add_variables_group(tab, 1, job_template) + end + dialog.save! + end + end + + private + + def add_options_group(tab, position, hosts) + tab.dialog_groups.build( + :display => "edit", + :label => "Options", + :position => position + ).tap do |dialog_group| + add_credential_dropdown(dialog_group, 0) + add_inventory_field(dialog_group, 1, hosts) + end + end + + def add_credential_dropdown(group, position) + group.dialog_fields.build( + :type => "DialogFieldDropDownList", + :name => "credential", + :data_type => "string", + :dynamic => true, + :display => "edit", + :required => false, + :label => "Credential", + :description => "The credential to run the playbook", + :reconfigurable => true, + :position => position, + :dialog_group => group + ).tap do |dialog_field| + dialog_field.resource_action.fqname = "AutomationManagement/AnsibleTower/Operations/Methods/AvailableCredentials" + end + end + + def add_inventory_field(group, position, hosts) + group.dialog_fields.build( + :type => "DialogFieldTextBox", + :name => "hosts", + :description => "A ';'-separated string to list hosts for the playbook to run at", + :data_type => "string", + :display => "edit", + :required => false, + :default_value => hosts, + :options => {:protected => false}, + :label => "Hosts", + :position => position, + :reconfigurable => true, + :dialog_group => group + ) + end + + def add_variables_group(tab, position, template) + tab.dialog_groups.build( + :display => "edit", + :label => "Variables", + :position => position + ).tap do |dialog_group| + template.variables.each_with_index do |(key, value), index| + value = value.to_json if [Hash, Array].include?(value.class) + add_variable_field(key, value, dialog_group, index) + end + end + end + + def add_variable_field(key, value, group, position) + group.dialog_fields.build( + :type => "DialogFieldTextBox", + :name => "param_#{key}", + :data_type => "string", + :display => "edit", + :required => false, + :default_value => value, + :label => key, + :description => key, + :reconfigurable => true, + :position => position, + :dialog_group => group, + :read_only => false + ) + end + end +end diff --git a/spec/models/dialog/ansible_playbook_service_dialog_spec.rb b/spec/models/dialog/ansible_playbook_service_dialog_spec.rb new file mode 100644 index 00000000000..896c7bb608e --- /dev/null +++ b/spec/models/dialog/ansible_playbook_service_dialog_spec.rb @@ -0,0 +1,61 @@ +describe Dialog::AnsiblePlaybookServiceDialog do + let(:playbook) { FactoryGirl.create(:configuration_script, :variables => nil) } + + describe "#create_dialog" do + it "creates a dialog for a playbook with variables" do + allow(playbook).to receive(:variables).and_return('some_extra_var' => 'blah', + 'other_extra_var' => {'name' => 'some_value'}, + 'array_extra_var' => [{'name' => 'some_value'}]) + + dialog = subject.create_dialog("mydialog1", playbook) + expect(dialog).to have_attributes(:label => 'mydialog1', :buttons => "submit,cancel") + + tabs = dialog.dialog_tabs + expect(tabs.size).to eq(1) + assert_main_tab(tabs[0]) + end + + it "creates a dialog for a playbook with no variables" do + dialog = described_class.create_dialog("mydialog2", playbook) + expect(dialog.dialog_tabs[0].dialog_groups.size).to eq(1) + end + end + + def assert_main_tab(tab) + assert_tab_attributes(tab) + + groups = tab.dialog_groups + expect(groups.size).to eq(2) + + assert_option_group(groups[0]) + assert_variables_group(groups[1]) + end + + def assert_tab_attributes(tab) + expect(tab).to have_attributes(:label => "Basic Information", :display => "edit") + end + + def assert_option_group(group) + expect(group).to have_attributes(:label => "Options", :display => "edit") + fields = group.dialog_fields + expect(fields.size).to eq(2) + assert_field(fields[0], DialogFieldDropDownList, :label => "Credential", :name => "credential", :dynamic => true, :required => false) + assert_field(fields[1], DialogFieldTextBox, :label => "Hosts", :name => "hosts", :required => false, :data_type => 'string') + end + + def assert_field(field, clss, attributes) + expect(field).to be_kind_of clss + expect(field).to have_attributes(attributes) + end + + def assert_variables_group(group) + expect(group).to have_attributes(:label => "Variables", :display => "edit") + + fields = group.dialog_fields + expect(fields.size).to eq(3) + + assert_field(fields[0], DialogFieldTextBox, :name => 'param_some_extra_var', :default_value => 'blah', :data_type => 'string') + assert_field(fields[1], DialogFieldTextBox, :name => 'param_other_extra_var', :default_value => '{"name":"some_value"}', :data_type => 'string') + assert_field(fields[2], DialogFieldTextBox, :name => 'param_array_extra_var', :default_value => '[{"name":"some_value"}]', :data_type => 'string') + end +end