diff --git a/app/controllers/foreman_salt/api/v2/salt_environments_controller.rb b/app/controllers/foreman_salt/api/v2/salt_environments_controller.rb index 7942fbd8..0a8cc9ca 100644 --- a/app/controllers/foreman_salt/api/v2/salt_environments_controller.rb +++ b/app/controllers/foreman_salt/api/v2/salt_environments_controller.rb @@ -5,6 +5,7 @@ class SaltEnvironmentsController < ::ForemanSalt::Api::V2::BaseController before_filter :find_resource, :except => [:index, :create] api :GET, '/salt_environments', N_('List all Salt environments') + param_group :search_and_pagination, ::Api::V2::BaseController def index @salt_environments = resource_scope_for_index end diff --git a/app/controllers/foreman_salt/api/v2/salt_minions_controller.rb b/app/controllers/foreman_salt/api/v2/salt_minions_controller.rb index eb4b5e1d..29ee812e 100644 --- a/app/controllers/foreman_salt/api/v2/salt_minions_controller.rb +++ b/app/controllers/foreman_salt/api/v2/salt_minions_controller.rb @@ -5,6 +5,7 @@ class SaltMinionsController < ::ForemanSalt::Api::V2::BaseController before_filter :find_resource, :except => [:index] api :GET, '/salt_minions', N_('List all Salt Minions') + param_group :search_and_pagination, ::Api::V2::BaseController def index @salt_minions = resource_scope_for_index end diff --git a/app/controllers/foreman_salt/api/v2/salt_states_controller.rb b/app/controllers/foreman_salt/api/v2/salt_states_controller.rb index bec15287..e68af170 100644 --- a/app/controllers/foreman_salt/api/v2/salt_states_controller.rb +++ b/app/controllers/foreman_salt/api/v2/salt_states_controller.rb @@ -10,6 +10,7 @@ class SaltStatesController < ::ForemanSalt::Api::V2::BaseController api :GET, '/salt_states', N_('List all Salt states') param :salt_environment_id, :identifier_dottable, :required => false, :desc => N_('Limit to a specific environment') + param_group :search_and_pagination, ::Api::V2::BaseController def index if @salt_environment @salt_states = resource_scope_for_index.joins(:salt_environments).where('salt_module_environments.salt_environment_id' => @salt_environment) @@ -46,18 +47,19 @@ def destroy api :POST, '/salt_states/import/:smart_proxy_id', N_('Import states from a salt master') param :smart_proxy_id, :identifier_dottable, :required => true, :desc => N_('Salt Smart Proxy ID') - param :salt_environment_ids, Array, :required => false, :desc => N_('Limit to a specific environments') + param :salt_environments, Array, :required => false, :desc => N_('Limit to a specific environments') param :actions, Array, :required => false, :desc => N_('Limit to specific actions: i.e. add, remove') param :dryrun, :bool, :required => false, :desc => N_('Dryrun only') def import - states = fetch_states_from_proxy(@proxy, params[:salt_environment_ids]) + states = fetch_states_from_proxy(@proxy, params[:salt_environments]) + unless params[:dryrun] states[:changes].each do |environment, state| - if state[:add].any? && (params[:actions].blank? || params[:actions].include?('add')) + if state[:add].present? && (params[:actions].blank? || params[:actions].include?('add')) add_to_environment(state[:add], environment) end - if state[:remove].any? && (params[:actions].blank? || params[:actions].include?('remove')) + if state[:remove].present? && (params[:actions].blank? || params[:actions].include?('remove')) remove_from_environment(state[:remove], environment) end end diff --git a/app/controllers/foreman_salt/salt_modules_controller.rb b/app/controllers/foreman_salt/salt_modules_controller.rb index 82ebd9e4..98a7bf1b 100644 --- a/app/controllers/foreman_salt/salt_modules_controller.rb +++ b/app/controllers/foreman_salt/salt_modules_controller.rb @@ -74,7 +74,6 @@ def apply_changes else params[:changed].each do |environment, states| next unless states[:add] || states[:remove] - environment = SaltEnvironment.find_or_create_by_name(environment) add_to_environment(JSON.load(states[:add]), environment) if states[:add] remove_from_environment(JSON.load(states[:remove]), environment) if states[:remove] diff --git a/app/controllers/foreman_salt/state_importer.rb b/app/controllers/foreman_salt/state_importer.rb index 25848388..028f1093 100644 --- a/app/controllers/foreman_salt/state_importer.rb +++ b/app/controllers/foreman_salt/state_importer.rb @@ -46,13 +46,17 @@ def fetch_states_from_proxy(proxy, environments = nil) end def add_to_environment(states, environment) + environment = SaltEnvironment.find_or_create_by_name(environment) + states.each do |state_name| state = SaltModule.find_or_create_by_name(state_name) - state.salt_environments << SaltEnvironment.find(environment) + state.salt_environments << environment unless state.salt_environments.include? environment end end def remove_from_environment(states, environment) + return unless (environment = SaltEnvironment.find(environment)) + states.each do |state_name| state = SaltModule.find(state_name) state.salt_environments.delete(environment) if state diff --git a/app/views/foreman_salt/api/v2/salt_environments/show.json.rabl b/app/views/foreman_salt/api/v2/salt_environments/show.json.rabl index 32115bc6..da44589e 100644 --- a/app/views/foreman_salt/api/v2/salt_environments/show.json.rabl +++ b/app/views/foreman_salt/api/v2/salt_environments/show.json.rabl @@ -1,3 +1,7 @@ object @salt_environment -extends "foreman_salt/api/v2/salt_environments/base" +extends 'foreman_salt/api/v2/salt_environments/base' + +child :salt_modules => :salt_states do + extends 'foreman_salt/api/v2/salt_states/base' +end diff --git a/app/views/foreman_salt/api/v2/salt_states/base.json.rabl b/app/views/foreman_salt/api/v2/salt_states/base.json.rabl index dd18450c..63d0c593 100644 --- a/app/views/foreman_salt/api/v2/salt_states/base.json.rabl +++ b/app/views/foreman_salt/api/v2/salt_states/base.json.rabl @@ -1,3 +1,3 @@ object @salt_state -attributes :id, :name +attributes :id, :name, :salt_environment diff --git a/app/views/foreman_salt/api/v2/salt_states/show.json.rabl b/app/views/foreman_salt/api/v2/salt_states/show.json.rabl index f6b6852a..69cc72fa 100644 --- a/app/views/foreman_salt/api/v2/salt_states/show.json.rabl +++ b/app/views/foreman_salt/api/v2/salt_states/show.json.rabl @@ -1,3 +1,12 @@ object @salt_state -extends "foreman_salt/api/v2/salt_states/base" +extends 'foreman_salt/api/v2/salt_states/base' + +child :hostgroups do + extends 'api/v2/hostgroups/base' +end + +child :salt_environments do + extends 'foreman_salt/api/v2/salt_environments/base' +end + diff --git a/test/functional/api/v2/salt_states_controller_test.rb b/test/functional/api/v2/salt_states_controller_test.rb index 62eec8f5..835d0b08 100644 --- a/test/functional/api/v2/salt_states_controller_test.rb +++ b/test/functional/api/v2/salt_states_controller_test.rb @@ -29,5 +29,58 @@ class Api::V2::SaltStatesControllerTest < ActionController::TestCase end assert_response :success end + + context 'importing' do + setup do + @proxy = FactoryGirl.create :smart_proxy, :with_salt_feature + @states = {'env1' => %w(state1 state2 state3), + 'env2' => %w(state1 state2)} + + ::ProxyAPI::Salt.any_instance.stubs(:states_list).returns(@states) + end + + test 'should import' do + post :import, :smart_proxy_id => @proxy.id + + assert_response :success + + @states.each do |env, states| + environment = ::ForemanSalt::SaltEnvironment.find(env) + assert_blank environment.salt_modules.map(&:name) - states + end + end + + test 'should import only from a given environment' do + post :import, :smart_proxy_id => @proxy.id, :salt_environments => ['env2'] + assert_response :success + refute ::ForemanSalt::SaltEnvironment.where(:name => 'env1').first + assert ::ForemanSalt::SaltEnvironment.where(:name => 'env2').first + end + + test 'should limit actions to add' do + env = FactoryGirl.create :salt_environment + state = FactoryGirl.create :salt_module, :salt_environments => [env] + + post :import, :smart_proxy_id => @proxy.id, :actions => ['add'] + assert_response :success + assert ::ForemanSalt::SaltModule.where(:id => state).first + assert ::ForemanSalt::SaltModule.where(:name => 'state1').first + end + + test 'should limit actions to remove' do + state = FactoryGirl.create :salt_module + post :import, :smart_proxy_id => @proxy.id, :actions => ['remove'] + assert_response :success + refute ::ForemanSalt::SaltModule.where(:id => state).first + refute ::ForemanSalt::SaltModule.where(:name => 'state1').first + end + + test 'dryrun should do nothing' do + post :import, :smart_proxy_id => @proxy.id, :dryrun => true + assert_response :success + refute ::ForemanSalt::SaltModule.all.any? + refute ::ForemanSalt::SaltEnvironment.all.any? + end + end end end diff --git a/test/integration/salt_module_test.rb b/test/integration/salt_module_test.rb index 338475c1..abfbce2b 100644 --- a/test/integration/salt_module_test.rb +++ b/test/integration/salt_module_test.rb @@ -2,8 +2,17 @@ module ForemanSalt class SaltModuleTest < ActionDispatch::IntegrationTest + setup do + User.current = User.anonymous_admin + + states = %w(state1 state2 state3 state4) + state_list = {'env1' => states, 'env2' => states} + + ::ProxyAPI::Salt.any_instance.stubs(:states_list).returns(state_list) + end + test 'index page' do - FactoryGirl.create_list :salt_module, 50 + FactoryGirl.create_list :salt_module, 5 assert_index_page(salt_modules_path, 'Salt State', 'New Salt State') end @@ -22,5 +31,25 @@ class SaltModuleTest < ActionDispatch::IntegrationTest assert_submit_button(salt_modules_path) assert page.has_link? 'some_other_name' end + + test 'import states' do + proxy = FactoryGirl.create :smart_proxy, :with_salt_feature + state = FactoryGirl.create :salt_module, :salt_environments => [FactoryGirl.create(:salt_environment)] + + visit salt_modules_path + click_link "Import from #{proxy.name}" + + assert page.has_selector?('td', :text => 'env1'), 'Could not find env1 on importer page' + assert page.has_selector?('td', :text => 'Add'), 'Could not find env1 on importer page' + assert page.has_selector?('td', :text => 'state1, state2, state3, and state4'), 'Could not find states on importer page' + + assert page.has_selector?('td', :text => 'Remove'), 'Could not find remove on importer page' + assert page.has_selector?('td', :text => state.name), 'Could not find state to remove' + + all('input.state_check').each { |checkbox| check(checkbox[:id]) } + + click_button 'Update' + assert page.has_link? 'state1' + end end end