foreman_remote_execution 1.4.5 → 1.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/.hound.yml +13 -0
 - data/.rubocop.yml +9 -0
 - data/app/controllers/api/v2/job_invocations_controller.rb +49 -6
 - data/app/controllers/job_invocations_controller.rb +29 -1
 - data/app/helpers/remote_execution_helper.rb +5 -5
 - data/app/lib/actions/remote_execution/run_host_job.rb +32 -20
 - data/app/lib/actions/remote_execution/run_hosts_job.rb +13 -8
 - data/app/models/foreign_input_set.rb +1 -1
 - data/app/models/job_invocation.rb +23 -1
 - data/app/models/job_invocation_composer.rb +25 -3
 - data/app/models/job_template.rb +2 -2
 - data/app/models/remote_execution_feature.rb +22 -10
 - data/app/models/setting/remote_execution.rb +34 -10
 - data/app/models/ssh_execution_provider.rb +8 -0
 - data/app/models/template_input.rb +1 -1
 - data/app/views/api/v2/job_templates/base.json.rabl +1 -1
 - data/app/views/job_invocations/_form.html.erb +11 -5
 - data/app/views/job_invocations/_tab_hosts.html.erb +1 -1
 - data/app/views/job_invocations/index.html.erb +1 -1
 - data/app/views/job_templates/index.html.erb +1 -1
 - data/app/views/remote_execution_features/index.html.erb +1 -1
 - data/app/views/template_inputs/_invocation_form.html.erb +2 -2
 - data/app/views/template_invocations/show.html.erb +1 -1
 - data/config/routes.rb +5 -0
 - data/db/migrate/20160113162007_expand_all_template_invocations.rb +1 -1
 - data/db/migrate/20171129103615_add_secrets_to_job_invocations.rb +6 -0
 - data/db/migrate/20180202072115_add_notification_builder_to_remote_execution_feature.rb +5 -0
 - data/db/migrate/20180202123215_add_feature_id_to_job_invocation.rb +6 -0
 - data/db/migrate/20180226095631_change_task_id_to_uuid.rb +31 -0
 - data/foreman_remote_execution.gemspec +1 -1
 - data/lib/foreman_remote_execution/engine.rb +3 -1
 - data/lib/foreman_remote_execution/version.rb +1 -1
 - data/test/factories/foreman_remote_execution_factories.rb +6 -0
 - data/test/functional/api/v2/job_invocations_controller_test.rb +139 -32
 - data/test/functional/job_invocations_controller_test.rb +49 -0
 - data/test/unit/actions/run_hosts_job_test.rb +10 -6
 - data/test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb +1 -1
 - data/test/unit/job_invocation_composer_test.rb +43 -1
 - metadata +14 -10
 - data/app/models/concerns/foreman_remote_execution/exportable.rb +0 -71
 - data/test/unit/concerns/exportable_test.rb +0 -88
 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test_plugin_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class JobInvocationsControllerTest < ActionController::TestCase
         
     | 
| 
      
 6 
     | 
    
         
            +
              test 'should parse inputs coming from the URL params' do
         
     | 
| 
      
 7 
     | 
    
         
            +
                template = FactoryBot.create(:job_template, :with_input)
         
     | 
| 
      
 8 
     | 
    
         
            +
                feature = FactoryBot.create(:remote_execution_feature,
         
     | 
| 
      
 9 
     | 
    
         
            +
                                            :job_template => template)
         
     | 
| 
      
 10 
     | 
    
         
            +
                params = {
         
     | 
| 
      
 11 
     | 
    
         
            +
                  feature: feature.label,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  inputs: { template.template_inputs.first.name => 'foobar' }
         
     | 
| 
      
 13 
     | 
    
         
            +
                }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                get :new, params: params, session: set_session_user
         
     | 
| 
      
 16 
     | 
    
         
            +
                template_invocation_params = [
         
     | 
| 
      
 17 
     | 
    
         
            +
                  {
         
     | 
| 
      
 18 
     | 
    
         
            +
                    'input_values' =>
         
     | 
| 
      
 19 
     | 
    
         
            +
                    [
         
     | 
| 
      
 20 
     | 
    
         
            +
                      {
         
     | 
| 
      
 21 
     | 
    
         
            +
                        'value' => 'foobar',
         
     | 
| 
      
 22 
     | 
    
         
            +
                        'template_input_id' => template.template_inputs.first.id
         
     | 
| 
      
 23 
     | 
    
         
            +
                      }
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 25 
     | 
    
         
            +
                    'template_id' => template.id
         
     | 
| 
      
 26 
     | 
    
         
            +
                  }
         
     | 
| 
      
 27 
     | 
    
         
            +
                ]
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert_equal(template_invocation_params,
         
     | 
| 
      
 29 
     | 
    
         
            +
                             assigns(:composer).params['template_invocations'])
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              test 'should allow no inputs' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                template = FactoryBot.create(:job_template)
         
     | 
| 
      
 34 
     | 
    
         
            +
                feature = FactoryBot.create(:remote_execution_feature,
         
     | 
| 
      
 35 
     | 
    
         
            +
                                            :job_template => template)
         
     | 
| 
      
 36 
     | 
    
         
            +
                params = {
         
     | 
| 
      
 37 
     | 
    
         
            +
                  feature: feature.label,
         
     | 
| 
      
 38 
     | 
    
         
            +
                }
         
     | 
| 
      
 39 
     | 
    
         
            +
                get :new, params: params, session: set_session_user
         
     | 
| 
      
 40 
     | 
    
         
            +
                template_invocation_params = [
         
     | 
| 
      
 41 
     | 
    
         
            +
                  {
         
     | 
| 
      
 42 
     | 
    
         
            +
                    'template_id' => template.id,
         
     | 
| 
      
 43 
     | 
    
         
            +
                    'input_values' => {}
         
     | 
| 
      
 44 
     | 
    
         
            +
                  }
         
     | 
| 
      
 45 
     | 
    
         
            +
                ]
         
     | 
| 
      
 46 
     | 
    
         
            +
                assert_equal(template_invocation_params,
         
     | 
| 
      
 47 
     | 
    
         
            +
                             assigns(:composer).params['template_invocations'])
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,5 +1,5 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
1 
     | 
    
         
             
            require 'test_plugin_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'securerandom'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            module ForemanRemoteExecution
         
     | 
| 
       5 
5 
     | 
    
         
             
              class RunHostsJobTest < ActiveSupport::TestCase
         
     | 
| 
         @@ -12,12 +12,15 @@ module ForemanRemoteExecution 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  FactoryBot.build(:job_invocation, :with_template).tap do |invocation|
         
     | 
| 
       13 
13 
     | 
    
         
             
                    invocation.targeting = targeting
         
     | 
| 
       14 
14 
     | 
    
         
             
                    invocation.description = 'Some short description'
         
     | 
| 
      
 15 
     | 
    
         
            +
                    invocation.password = 'changeme'
         
     | 
| 
      
 16 
     | 
    
         
            +
                    invocation.key_passphrase = 'changemetoo'
         
     | 
| 
       15 
17 
     | 
    
         
             
                    invocation.save
         
     | 
| 
       16 
18 
     | 
    
         
             
                  end
         
     | 
| 
       17 
19 
     | 
    
         
             
                end
         
     | 
| 
       18 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
                let(:uuid) { SecureRandom.uuid }
         
     | 
| 
       19 
22 
     | 
    
         
             
                let(:task) do
         
     | 
| 
       20 
     | 
    
         
            -
                  OpenStruct.new(:id =>  
     | 
| 
      
 23 
     | 
    
         
            +
                  OpenStruct.new(:id => uuid).tap do |o|
         
     | 
| 
       21 
24 
     | 
    
         
             
                    o.stubs(:add_missing_task_groups)
         
     | 
| 
       22 
25 
     | 
    
         
             
                    o.stubs(:task_groups).returns([])
         
     | 
| 
       23 
26 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -76,15 +79,16 @@ module ForemanRemoteExecution 
     | 
|
| 
       76 
79 
     | 
    
         | 
| 
       77 
80 
     | 
    
         
             
                it 'uses the BindJobInvocation middleware' do
         
     | 
| 
       78 
81 
     | 
    
         
             
                  planned
         
     | 
| 
       79 
     | 
    
         
            -
                  job_invocation.task_id.must_equal  
     | 
| 
      
 82 
     | 
    
         
            +
                  job_invocation.task_id.must_equal uuid
         
     | 
| 
       80 
83 
     | 
    
         
             
                end
         
     | 
| 
       81 
84 
     | 
    
         | 
| 
       82 
85 
     | 
    
         
             
                # In plan phase this is handled by #action_subject
         
     | 
| 
       83 
86 
     | 
    
         
             
                #   which is expected in tests
         
     | 
| 
       84 
87 
     | 
    
         
             
                it 'sets input in delay phase when delayed' do
         
     | 
| 
       85 
     | 
    
         
            -
                  delayed.input[:job_invocation] 
     | 
| 
       86 
     | 
    
         
            -
                   
     | 
| 
       87 
     | 
    
         
            -
                   
     | 
| 
      
 88 
     | 
    
         
            +
                  job_invocation_hash = delayed.input[:job_invocation]
         
     | 
| 
      
 89 
     | 
    
         
            +
                  job_invocation_hash['id'].must_equal job_invocation.id
         
     | 
| 
      
 90 
     | 
    
         
            +
                  job_invocation_hash['name'].must_equal job_invocation.job_category
         
     | 
| 
      
 91 
     | 
    
         
            +
                  job_invocation_hash['description'].must_equal job_invocation.description
         
     | 
| 
       88 
92 
     | 
    
         
             
                  planned # To make the expectations happy
         
     | 
| 
       89 
93 
     | 
    
         
             
                end
         
     | 
| 
       90 
94 
     | 
    
         | 
| 
         @@ -14,7 +14,7 @@ class ForemanRemoteExecutionForemanTasksCleanerExtensionsTest < ActiveSupport::T 
     | 
|
| 
       14 
14 
     | 
    
         
             
                job.reload
         
     | 
| 
       15 
15 
     | 
    
         
             
                job.task.must_be :nil?
         
     | 
| 
       16 
16 
     | 
    
         
             
                job.task_id.wont_be :nil?
         
     | 
| 
       17 
     | 
    
         
            -
                ForemanTasks::Cleaner.new(:filter => ' 
     | 
| 
      
 17 
     | 
    
         
            +
                ForemanTasks::Cleaner.new(:filter => '').delete
         
     | 
| 
       18 
18 
     | 
    
         
             
                JobInvocation.where(:id => job.id).must_be :empty?
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         
             
            end
         
     | 
| 
         @@ -412,6 +412,7 @@ class JobInvocationComposerTest < ActiveSupport::TestCase 
     | 
|
| 
       412 
412 
     | 
    
         
             
                          }
         
     | 
| 
       413 
413 
     | 
    
         
             
                        } }
         
     | 
| 
       414 
414 
     | 
    
         
             
                    end
         
     | 
| 
      
 415 
     | 
    
         
            +
             
     | 
| 
       415 
416 
     | 
    
         
             
                    let(:params) do
         
     | 
| 
       416 
417 
     | 
    
         
             
                      { :job_invocation => { :providers => { :ssh => ssh_params } }, :targeting => { :search_query => "name = #{host.name}" } }.with_indifferent_access
         
     | 
| 
       417 
418 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -476,6 +477,30 @@ class JobInvocationComposerTest < ActiveSupport::TestCase 
     | 
|
| 
       476 
477 
     | 
    
         
             
                    end
         
     | 
| 
       477 
478 
     | 
    
         
             
                  end
         
     | 
| 
       478 
479 
     | 
    
         | 
| 
      
 480 
     | 
    
         
            +
                  describe '#password' do
         
     | 
| 
      
 481 
     | 
    
         
            +
                    let(:password) { 'changeme' }
         
     | 
| 
      
 482 
     | 
    
         
            +
                    let(:params) do
         
     | 
| 
      
 483 
     | 
    
         
            +
                      { :job_invocation => { :password => password }}.with_indifferent_access
         
     | 
| 
      
 484 
     | 
    
         
            +
                    end
         
     | 
| 
      
 485 
     | 
    
         
            +
             
     | 
| 
      
 486 
     | 
    
         
            +
                    it 'sets the password properly' do
         
     | 
| 
      
 487 
     | 
    
         
            +
                      composer
         
     | 
| 
      
 488 
     | 
    
         
            +
                      composer.job_invocation.password.must_equal password
         
     | 
| 
      
 489 
     | 
    
         
            +
                    end
         
     | 
| 
      
 490 
     | 
    
         
            +
                  end
         
     | 
| 
      
 491 
     | 
    
         
            +
             
     | 
| 
      
 492 
     | 
    
         
            +
                  describe '#key_passphrase' do
         
     | 
| 
      
 493 
     | 
    
         
            +
                    let(:key_passphrase) { 'changeme' }
         
     | 
| 
      
 494 
     | 
    
         
            +
                    let(:params) do
         
     | 
| 
      
 495 
     | 
    
         
            +
                      { :job_invocation => { :key_passphrase => key_passphrase }}
         
     | 
| 
      
 496 
     | 
    
         
            +
                    end
         
     | 
| 
      
 497 
     | 
    
         
            +
             
     | 
| 
      
 498 
     | 
    
         
            +
                    it 'sets the key passphrase properly' do
         
     | 
| 
      
 499 
     | 
    
         
            +
                      composer
         
     | 
| 
      
 500 
     | 
    
         
            +
                      composer.job_invocation.key_passphrase.must_equal key_passphrase
         
     | 
| 
      
 501 
     | 
    
         
            +
                    end
         
     | 
| 
      
 502 
     | 
    
         
            +
                  end
         
     | 
| 
      
 503 
     | 
    
         
            +
             
     | 
| 
       479 
504 
     | 
    
         
             
                  describe '#targeting' do
         
     | 
| 
       480 
505 
     | 
    
         
             
                    it 'triggers targeting on job_invocation' do
         
     | 
| 
       481 
506 
     | 
    
         
             
                      composer
         
     | 
| 
         @@ -630,7 +655,7 @@ class JobInvocationComposerTest < ActiveSupport::TestCase 
     | 
|
| 
       630 
655 
     | 
    
         
             
                      },
         
     | 
| 
       631 
656 
     | 
    
         
             
                      :targeting_type => 'static_query',
         
     | 
| 
       632 
657 
     | 
    
         
             
                      :search_query => 'some hosts',
         
     | 
| 
       633 
     | 
    
         
            -
                      :inputs => {input1.name => 'some_value'}}
         
     | 
| 
      
 658 
     | 
    
         
            +
                      :inputs => { input1.name => 'some_value' } }
         
     | 
| 
       634 
659 
     | 
    
         
             
                  end
         
     | 
| 
       635 
660 
     | 
    
         | 
| 
       636 
661 
     | 
    
         
             
                  it 'sets the concurrency level and time span based on the input' do
         
     | 
| 
         @@ -640,6 +665,23 @@ class JobInvocationComposerTest < ActiveSupport::TestCase 
     | 
|
| 
       640 
665 
     | 
    
         
             
                  end
         
     | 
| 
       641 
666 
     | 
    
         
             
                end
         
     | 
| 
       642 
667 
     | 
    
         | 
| 
      
 668 
     | 
    
         
            +
                context 'with rex feature defined' do
         
     | 
| 
      
 669 
     | 
    
         
            +
                  let(:feature) { FactoryBot.create(:remote_execution_feature) }
         
     | 
| 
      
 670 
     | 
    
         
            +
                  let(:params) do
         
     | 
| 
      
 671 
     | 
    
         
            +
                    { :job_category => trying_job_template_1.job_category,
         
     | 
| 
      
 672 
     | 
    
         
            +
                      :job_template_id => trying_job_template_1.id,
         
     | 
| 
      
 673 
     | 
    
         
            +
                      :remote_execution_feature_id => feature.id,
         
     | 
| 
      
 674 
     | 
    
         
            +
                      :targeting_type => 'static_query',
         
     | 
| 
      
 675 
     | 
    
         
            +
                      :search_query => 'some hosts',
         
     | 
| 
      
 676 
     | 
    
         
            +
                      :inputs => { input1.name => 'some_value' } }
         
     | 
| 
      
 677 
     | 
    
         
            +
                  end
         
     | 
| 
      
 678 
     | 
    
         
            +
             
     | 
| 
      
 679 
     | 
    
         
            +
                  it 'sets the remote execution feature based on the input' do
         
     | 
| 
      
 680 
     | 
    
         
            +
                    assert composer.save!
         
     | 
| 
      
 681 
     | 
    
         
            +
                    composer.job_invocation.remote_execution_feature.must_equal feature
         
     | 
| 
      
 682 
     | 
    
         
            +
                  end
         
     | 
| 
      
 683 
     | 
    
         
            +
                end
         
     | 
| 
      
 684 
     | 
    
         
            +
             
     | 
| 
       643 
685 
     | 
    
         
             
                context 'with invalid targeting' do
         
     | 
| 
       644 
686 
     | 
    
         
             
                  let(:params) do
         
     | 
| 
       645 
687 
     | 
    
         
             
                    { :job_category => trying_job_template_1.job_category,
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: foreman_remote_execution
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1.4. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.4.6
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Foreman Remote Execution team
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2018- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-03-12 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: deface
         
     | 
| 
         @@ -56,16 +56,16 @@ dependencies: 
     | 
|
| 
       56 
56 
     | 
    
         
             
              name: foreman-tasks
         
     | 
| 
       57 
57 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       58 
58 
     | 
    
         
             
                requirements:
         
     | 
| 
       59 
     | 
    
         
            -
                - - " 
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       60 
60 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       61 
     | 
    
         
            -
                    version: 0. 
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '0.12'
         
     | 
| 
       62 
62 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       63 
63 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       64 
64 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       65 
65 
     | 
    
         
             
                requirements:
         
     | 
| 
       66 
     | 
    
         
            -
                - - " 
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
       67 
67 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       68 
     | 
    
         
            -
                    version: 0. 
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '0.12'
         
     | 
| 
       69 
69 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       70 
70 
     | 
    
         
             
              name: factory_bot_rails
         
     | 
| 
       71 
71 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -119,6 +119,7 @@ extra_rdoc_files: 
     | 
|
| 
       119 
119 
     | 
    
         
             
            - LICENSE
         
     | 
| 
       120 
120 
     | 
    
         
             
            files:
         
     | 
| 
       121 
121 
     | 
    
         
             
            - ".gitignore"
         
     | 
| 
      
 122 
     | 
    
         
            +
            - ".hound.yml"
         
     | 
| 
       122 
123 
     | 
    
         
             
            - ".rubocop.yml"
         
     | 
| 
       123 
124 
     | 
    
         
             
            - ".rubocop_todo.yml"
         
     | 
| 
       124 
125 
     | 
    
         
             
            - ".tx/config"
         
     | 
| 
         @@ -158,7 +159,6 @@ files: 
     | 
|
| 
       158 
159 
     | 
    
         
             
            - app/mailers/.gitkeep
         
     | 
| 
       159 
160 
     | 
    
         
             
            - app/models/concerns/foreman_remote_execution/bookmark_extensions.rb
         
     | 
| 
       160 
161 
     | 
    
         
             
            - app/models/concerns/foreman_remote_execution/errors_flattener.rb
         
     | 
| 
       161 
     | 
    
         
            -
            - app/models/concerns/foreman_remote_execution/exportable.rb
         
     | 
| 
       162 
162 
     | 
    
         
             
            - app/models/concerns/foreman_remote_execution/foreman_tasks_cleaner_extensions.rb
         
     | 
| 
       163 
163 
     | 
    
         
             
            - app/models/concerns/foreman_remote_execution/foreman_tasks_task_extensions.rb
         
     | 
| 
       164 
164 
     | 
    
         
             
            - app/models/concerns/foreman_remote_execution/foreman_tasks_triggering_extensions.rb
         
     | 
| 
         @@ -294,8 +294,12 @@ files: 
     | 
|
| 
       294 
294 
     | 
    
         
             
            - db/migrate/20160926225841_update_template_input_value.rb
         
     | 
| 
       295 
295 
     | 
    
         
             
            - db/migrate/20170110145641_add_host_action_button_to_remote_execution_feature.rb
         
     | 
| 
       296 
296 
     | 
    
         
             
            - db/migrate/20170613101039_add_timeout_to_job_templates_and_job_invocations.rb
         
     | 
| 
      
 297 
     | 
    
         
            +
            - db/migrate/20171129103615_add_secrets_to_job_invocations.rb
         
     | 
| 
       297 
298 
     | 
    
         
             
            - db/migrate/20180110104432_rename_template_invocation_permission.rb
         
     | 
| 
       298 
299 
     | 
    
         
             
            - db/migrate/20180112125015_fix_taxable_taxonomies_job_template.rb
         
     | 
| 
      
 300 
     | 
    
         
            +
            - db/migrate/20180202072115_add_notification_builder_to_remote_execution_feature.rb
         
     | 
| 
      
 301 
     | 
    
         
            +
            - db/migrate/20180202123215_add_feature_id_to_job_invocation.rb
         
     | 
| 
      
 302 
     | 
    
         
            +
            - db/migrate/20180226095631_change_task_id_to_uuid.rb
         
     | 
| 
       299 
303 
     | 
    
         
             
            - db/seeds.d/50-notification_blueprints.rb
         
     | 
| 
       300 
304 
     | 
    
         
             
            - db/seeds.d/60-ssh_proxy_feature.rb
         
     | 
| 
       301 
305 
     | 
    
         
             
            - db/seeds.d/70-job_templates.rb
         
     | 
| 
         @@ -339,9 +343,9 @@ files: 
     | 
|
| 
       339 
343 
     | 
    
         
             
            - test/functional/api/v2/job_templates_controller_test.rb
         
     | 
| 
       340 
344 
     | 
    
         
             
            - test/functional/api/v2/remote_execution_features_controller_test.rb
         
     | 
| 
       341 
345 
     | 
    
         
             
            - test/functional/api/v2/template_inputs_controller_test.rb
         
     | 
| 
      
 346 
     | 
    
         
            +
            - test/functional/job_invocations_controller_test.rb
         
     | 
| 
       342 
347 
     | 
    
         
             
            - test/test_plugin_helper.rb
         
     | 
| 
       343 
348 
     | 
    
         
             
            - test/unit/actions/run_hosts_job_test.rb
         
     | 
| 
       344 
     | 
    
         
            -
            - test/unit/concerns/exportable_test.rb
         
     | 
| 
       345 
349 
     | 
    
         
             
            - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
         
     | 
| 
       346 
350 
     | 
    
         
             
            - test/unit/concerns/host_extensions_test.rb
         
     | 
| 
       347 
351 
     | 
    
         
             
            - test/unit/concerns/nic_extensions_test.rb
         
     | 
| 
         @@ -376,7 +380,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       376 
380 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       377 
381 
     | 
    
         
             
            requirements: []
         
     | 
| 
       378 
382 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       379 
     | 
    
         
            -
            rubygems_version: 2. 
     | 
| 
      
 383 
     | 
    
         
            +
            rubygems_version: 2.7.3
         
     | 
| 
       380 
384 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       381 
385 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       382 
386 
     | 
    
         
             
            summary: A plugin bringing remote execution to the Foreman, completing the config
         
     | 
| 
         @@ -390,9 +394,9 @@ test_files: 
     | 
|
| 
       390 
394 
     | 
    
         
             
            - test/functional/api/v2/job_templates_controller_test.rb
         
     | 
| 
       391 
395 
     | 
    
         
             
            - test/functional/api/v2/remote_execution_features_controller_test.rb
         
     | 
| 
       392 
396 
     | 
    
         
             
            - test/functional/api/v2/template_inputs_controller_test.rb
         
     | 
| 
      
 397 
     | 
    
         
            +
            - test/functional/job_invocations_controller_test.rb
         
     | 
| 
       393 
398 
     | 
    
         
             
            - test/test_plugin_helper.rb
         
     | 
| 
       394 
399 
     | 
    
         
             
            - test/unit/actions/run_hosts_job_test.rb
         
     | 
| 
       395 
     | 
    
         
            -
            - test/unit/concerns/exportable_test.rb
         
     | 
| 
       396 
400 
     | 
    
         
             
            - test/unit/concerns/foreman_tasks_cleaner_extensions_test.rb
         
     | 
| 
       397 
401 
     | 
    
         
             
            - test/unit/concerns/host_extensions_test.rb
         
     | 
| 
       398 
402 
     | 
    
         
             
            - test/unit/concerns/nic_extensions_test.rb
         
     | 
| 
         @@ -1,71 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # This concern makes it easy to export an ActiveRecord object with specified
         
     | 
| 
       2 
     | 
    
         
            -
            # attributes and associations in a particular format.  If a specified
         
     | 
| 
       3 
     | 
    
         
            -
            # assocation also includes this concern, then it will likewise be exported.
         
     | 
| 
       4 
     | 
    
         
            -
            #
         
     | 
| 
       5 
     | 
    
         
            -
            # Custom attributes can be specified with a custom export lambda in an options
         
     | 
| 
       6 
     | 
    
         
            -
            # hash.
         
     | 
| 
       7 
     | 
    
         
            -
            #
         
     | 
| 
       8 
     | 
    
         
            -
            # Example:
         
     | 
| 
       9 
     | 
    
         
            -
            #   attr_exportable :name, :address, :company => ->(user) { user.company.name }
         
     | 
| 
       10 
     | 
    
         
            -
            #
         
     | 
| 
       11 
     | 
    
         
            -
            module ForemanRemoteExecution
         
     | 
| 
       12 
     | 
    
         
            -
              module Exportable
         
     | 
| 
       13 
     | 
    
         
            -
                extend ActiveSupport::Concern
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                def to_export(include_blank = true)
         
     | 
| 
       16 
     | 
    
         
            -
                  self.class.exportable_attributes.keys.inject({}) do |hash, attribute|
         
     | 
| 
       17 
     | 
    
         
            -
                    value = export_attr(attribute, self.class.exportable_attributes[attribute], include_blank)
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                    # Rails considers false blank, but if a boolean value is explicitly set false, we want to ensure we export it.
         
     | 
| 
       20 
     | 
    
         
            -
                    if include_blank || value.present? || value == false
         
     | 
| 
       21 
     | 
    
         
            -
                      hash.update(attribute => value)
         
     | 
| 
       22 
     | 
    
         
            -
                    else
         
     | 
| 
       23 
     | 
    
         
            -
                      hash
         
     | 
| 
       24 
     | 
    
         
            -
                    end
         
     | 
| 
       25 
     | 
    
         
            -
                  end.stringify_keys
         
     | 
| 
       26 
     | 
    
         
            -
                end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
                # Export a particular attribute or association.
         
     | 
| 
       29 
     | 
    
         
            -
                #   - If our exportable_attributes value is callable, we call it with self as an argument
         
     | 
| 
       30 
     | 
    
         
            -
                #   - If our object is iterable, then we export each item
         
     | 
| 
       31 
     | 
    
         
            -
                #   - If the attribute or association also includes this concern, call to_export on it
         
     | 
| 
       32 
     | 
    
         
            -
                def export_attr(attribute, exporter, include_blank)
         
     | 
| 
       33 
     | 
    
         
            -
                  value = if exporter.respond_to?(:call)
         
     | 
| 
       34 
     | 
    
         
            -
                            exporter.call(self)
         
     | 
| 
       35 
     | 
    
         
            -
                          elsif self.respond_to?(exporter)
         
     | 
| 
       36 
     | 
    
         
            -
                            self.send(exporter)
         
     | 
| 
       37 
     | 
    
         
            -
                          end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                  value = value.respond_to?(:map) ? export_iterable(value, include_blank) : value
         
     | 
| 
       40 
     | 
    
         
            -
                  value.respond_to?(:to_export) ? value.to_export(include_blank) : value
         
     | 
| 
       41 
     | 
    
         
            -
                end
         
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                # Exports each item in an iterable.  If it's a hash, then export each value.
         
     | 
| 
       44 
     | 
    
         
            -
                def export_iterable(items, include_blank)
         
     | 
| 
       45 
     | 
    
         
            -
                  if items.is_a?(Hash)
         
     | 
| 
       46 
     | 
    
         
            -
                    items.each { |key, value| items[key] = value.respond_to?(:to_export) ? value.to_export(include_blank) : value }
         
     | 
| 
       47 
     | 
    
         
            -
                    items.to_hash.stringify_keys
         
     | 
| 
       48 
     | 
    
         
            -
                  else
         
     | 
| 
       49 
     | 
    
         
            -
                    items.map { |item| item.respond_to?(:to_export) ? item.to_export(include_blank) : item }
         
     | 
| 
       50 
     | 
    
         
            -
                  end
         
     | 
| 
       51 
     | 
    
         
            -
                end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                module ClassMethods
         
     | 
| 
       54 
     | 
    
         
            -
                  attr_reader :exportable_attributes
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                  # Takes an array of exportable attributes, and a custom exports hash.  The
         
     | 
| 
       57 
     | 
    
         
            -
                  # custom exports hash should be a key/lambda pair used to export the
         
     | 
| 
       58 
     | 
    
         
            -
                  # particular attribute.
         
     | 
| 
       59 
     | 
    
         
            -
                  def attr_exportable(*args)
         
     | 
| 
       60 
     | 
    
         
            -
                    @exportable_attributes ||= {}
         
     | 
| 
       61 
     | 
    
         
            -
                    args.each do |arg|
         
     | 
| 
       62 
     | 
    
         
            -
                      if arg.is_a?(Hash)
         
     | 
| 
       63 
     | 
    
         
            -
                        @exportable_attributes.merge!(arg)
         
     | 
| 
       64 
     | 
    
         
            -
                      else
         
     | 
| 
       65 
     | 
    
         
            -
                        @exportable_attributes.merge!(arg => arg)
         
     | 
| 
       66 
     | 
    
         
            -
                      end
         
     | 
| 
       67 
     | 
    
         
            -
                    end
         
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
       69 
     | 
    
         
            -
                end
         
     | 
| 
       70 
     | 
    
         
            -
              end
         
     | 
| 
       71 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,88 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'test_plugin_helper'
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module ForemanRemoteExecution
         
     | 
| 
       4 
     | 
    
         
            -
              class ExportableTest < ActiveSupport::TestCase
         
     | 
| 
       5 
     | 
    
         
            -
                class SampleModel
         
     | 
| 
       6 
     | 
    
         
            -
                  include ::ForemanRemoteExecution::Exportable
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
                  attr_accessor :name, :attrs, :subnet, :mac, :password
         
     | 
| 
       9 
     | 
    
         
            -
                  attr_exportable :name, :attrs, :mac, :subnet, :mac => ->(m) { m.mac.upcase if m.mac },
         
     | 
| 
       10 
     | 
    
         
            -
                                                                :custom_attr => ->(m) { 'hello world' }
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  def attributes
         
     | 
| 
       13 
     | 
    
         
            -
                    {
         
     | 
| 
       14 
     | 
    
         
            -
                      'name' => name,
         
     | 
| 
       15 
     | 
    
         
            -
                      'attrs' => attrs,
         
     | 
| 
       16 
     | 
    
         
            -
                      'mac' => mac,
         
     | 
| 
       17 
     | 
    
         
            -
                      'password' => password,
         
     | 
| 
       18 
     | 
    
         
            -
                      'subnet' => subnet
         
     | 
| 
       19 
     | 
    
         
            -
                    }
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
       21 
     | 
    
         
            -
                end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                class SampleSubnet
         
     | 
| 
       24 
     | 
    
         
            -
                  include ::ForemanRemoteExecution::Exportable
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  attr_accessor :name, :network
         
     | 
| 
       27 
     | 
    
         
            -
                  attr_exportable :name, :network
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                  def attributes
         
     | 
| 
       30 
     | 
    
         
            -
                    {
         
     | 
| 
       31 
     | 
    
         
            -
                      'name' => name,
         
     | 
| 
       32 
     | 
    
         
            -
                      'network' => network
         
     | 
| 
       33 
     | 
    
         
            -
                    }
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                def setup
         
     | 
| 
       38 
     | 
    
         
            -
                  @subnet = SampleSubnet.new
         
     | 
| 
       39 
     | 
    
         
            -
                  @subnet.name = 'pxe'
         
     | 
| 
       40 
     | 
    
         
            -
                  @subnet.network = '192.168.122.0'
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                  @sample = SampleModel.new
         
     | 
| 
       43 
     | 
    
         
            -
                  @sample.name = 'name'
         
     | 
| 
       44 
     | 
    
         
            -
                  @sample.attrs = {'nested' => 'hash'}
         
     | 
| 
       45 
     | 
    
         
            -
                  @sample.subnet = @subnet
         
     | 
| 
       46 
     | 
    
         
            -
                  @sample.mac = 'aa:bb:cc:dd:ee:ff'
         
     | 
| 
       47 
     | 
    
         
            -
                  @sample.password = 'password'
         
     | 
| 
       48 
     | 
    
         
            -
                end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                test '#to_export includes all specified attributes' do
         
     | 
| 
       51 
     | 
    
         
            -
                  assert_equal %w(name attrs mac subnet custom_attr), @sample.to_export.keys
         
     | 
| 
       52 
     | 
    
         
            -
                end
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                test '#to_export does not include all attributes' do
         
     | 
| 
       55 
     | 
    
         
            -
                  assert_not_include @sample.to_export.keys, 'password'
         
     | 
| 
       56 
     | 
    
         
            -
                end
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                test '#to_export calls the lambda' do
         
     | 
| 
       59 
     | 
    
         
            -
                  export = @sample.to_export
         
     | 
| 
       60 
     | 
    
         
            -
                  assert_equal('AA:BB:CC:DD:EE:FF', export['mac'])
         
     | 
| 
       61 
     | 
    
         
            -
                  assert_equal(export['custom_attr'], 'hello world')
         
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                test '#to_export values are exported recursively' do
         
     | 
| 
       65 
     | 
    
         
            -
                  export = @sample.to_export
         
     | 
| 
       66 
     | 
    
         
            -
                  assert_equal('pxe', export['subnet']['name'])
         
     | 
| 
       67 
     | 
    
         
            -
                  assert_equal('192.168.122.0', export['subnet']['network'])
         
     | 
| 
       68 
     | 
    
         
            -
                end
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                test '#to_export nested hashes are primitive' do
         
     | 
| 
       71 
     | 
    
         
            -
                  @sample.attrs = {:foo => 'bar', :baz => 'qux'}.with_indifferent_access
         
     | 
| 
       72 
     | 
    
         
            -
                  export = @sample.to_export
         
     | 
| 
       73 
     | 
    
         
            -
                  assert_instance_of Hash, export['attrs']
         
     | 
| 
       74 
     | 
    
         
            -
                end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                test '#to_export includes blank values' do
         
     | 
| 
       77 
     | 
    
         
            -
                  @sample.attrs = {}
         
     | 
| 
       78 
     | 
    
         
            -
                  export = @sample.to_export
         
     | 
| 
       79 
     | 
    
         
            -
                  assert_instance_of Hash, export['attrs']
         
     | 
| 
       80 
     | 
    
         
            -
                end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                test '#to_export(false) does not include blank values' do
         
     | 
| 
       83 
     | 
    
         
            -
                  @sample.attrs = {}
         
     | 
| 
       84 
     | 
    
         
            -
                  export = @sample.to_export(false)
         
     | 
| 
       85 
     | 
    
         
            -
                  assert_nil export['attrs']
         
     | 
| 
       86 
     | 
    
         
            -
                end
         
     | 
| 
       87 
     | 
    
         
            -
              end
         
     | 
| 
       88 
     | 
    
         
            -
            end
         
     |