foreman_remote_execution 4.5.1 → 4.7.0
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 +4 -4
 - data/.github/workflows/ruby_ci.yml +7 -0
 - data/app/controllers/ui_job_wizard_controller.rb +7 -0
 - data/app/graphql/types/job_invocation.rb +16 -0
 - data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +5 -1
 - data/app/helpers/remote_execution_helper.rb +9 -3
 - data/app/lib/actions/remote_execution/run_hosts_job.rb +1 -1
 - data/app/models/job_invocation_composer.rb +3 -3
 - data/app/models/job_template.rb +1 -1
 - data/app/models/remote_execution_feature.rb +5 -1
 - data/app/models/remote_execution_provider.rb +1 -1
 - data/app/views/templates/ssh/module_action.erb +1 -0
 - data/app/views/templates/ssh/power_action.erb +2 -0
 - data/app/views/templates/ssh/puppet_run_once.erb +1 -0
 - data/foreman_remote_execution.gemspec +2 -4
 - data/lib/foreman_remote_execution/engine.rb +3 -0
 - data/lib/foreman_remote_execution/version.rb +1 -1
 - data/test/graphql/queries/job_invocation_query_test.rb +31 -0
 - data/test/graphql/queries/job_invocations_query_test.rb +35 -0
 - data/test/unit/concerns/host_extensions_test.rb +4 -4
 - data/test/unit/input_template_renderer_test.rb +1 -89
 - data/test/unit/job_invocation_composer_test.rb +1 -12
 - data/webpack/JobWizard/JobWizard.js +28 -8
 - data/webpack/JobWizard/JobWizard.scss +39 -0
 - data/webpack/JobWizard/JobWizardConstants.js +10 -0
 - data/webpack/JobWizard/JobWizardSelectors.js +9 -0
 - data/webpack/JobWizard/__tests__/fixtures.js +104 -2
 - data/webpack/JobWizard/__tests__/integration.test.js +13 -85
 - data/webpack/JobWizard/steps/AdvancedFields/AdvancedFields.js +21 -4
 - data/webpack/JobWizard/steps/AdvancedFields/DescriptionField.js +67 -0
 - data/webpack/JobWizard/steps/AdvancedFields/Fields.js +73 -59
 - data/webpack/JobWizard/steps/AdvancedFields/__tests__/AdvancedFields.test.js +135 -16
 - data/webpack/JobWizard/steps/AdvancedFields/__tests__/DescriptionField.test.js +23 -0
 - data/webpack/JobWizard/steps/CategoryAndTemplate/CategoryAndTemplate.test.js +122 -51
 - data/webpack/JobWizard/steps/Schedule/QueryType.js +48 -0
 - data/webpack/JobWizard/steps/Schedule/RepeatOn.js +61 -0
 - data/webpack/JobWizard/steps/Schedule/ScheduleType.js +25 -0
 - data/webpack/JobWizard/steps/Schedule/StartEndDates.js +51 -0
 - data/webpack/JobWizard/steps/Schedule/__tests__/StartEndDates.test.js +22 -0
 - data/webpack/JobWizard/steps/Schedule/index.js +41 -0
 - data/webpack/JobWizard/steps/form/FormHelpers.js +1 -0
 - data/webpack/JobWizard/steps/form/Formatter.js +149 -0
 - data/webpack/JobWizard/steps/form/NumberInput.js +33 -0
 - data/webpack/JobWizard/steps/form/SelectField.js +14 -2
 - data/webpack/JobWizard/steps/form/__tests__/Formatter.test.js.example +76 -0
 - data/webpack/__mocks__/foremanReact/components/SearchBar.js +18 -1
 - data/webpack/react_app/components/RecentJobsCard/JobStatusIcon.js +43 -0
 - data/webpack/react_app/components/RecentJobsCard/RecentJobsCard.js +72 -66
 - data/webpack/react_app/components/RecentJobsCard/RecentJobsTable.js +98 -0
 - data/webpack/react_app/components/RecentJobsCard/constants.js +11 -0
 - data/webpack/react_app/components/RecentJobsCard/styles.scss +11 -0
 - data/webpack/react_app/components/TargetingHosts/__tests__/__snapshots__/TargetingHostsPage.test.js.snap +1 -0
 - data/webpack/react_app/extend/fillRecentJobsCard.js +1 -1
 - metadata +23 -27
 - data/webpack/JobWizard/__tests__/JobWizard.test.js +0 -13
 - data/webpack/JobWizard/__tests__/__snapshots__/JobWizard.test.js.snap +0 -32
 - data/webpack/JobWizard/steps/AdvancedFields/__tests__/__snapshots__/AdvancedFields.test.js.snap +0 -249
 - data/webpack/JobWizard/steps/CategoryAndTemplate/__snapshots__/CategoryAndTemplate.test.js.snap +0 -113
 - data/webpack/JobWizard/steps/form/__tests__/GroupedSelectField.test.js +0 -38
 - data/webpack/JobWizard/steps/form/__tests__/SelectField.test.js +0 -23
 - data/webpack/JobWizard/steps/form/__tests__/__snapshots__/GroupedSelectField.test.js.snap +0 -37
 - data/webpack/JobWizard/steps/form/__tests__/__snapshots__/SelectField.test.js.snap +0 -23
 - data/webpack/react_app/components/RecentJobsCard/styles.css +0 -15
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 742978171c8d62de9fdf9e14b2be742235dc1cce90c0c522871d65a90ee1f612
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: caae67492773457e26461ae6e39addec2cc1b105bf387a9cf0dbfc667ad25102
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: e40d5600dbe09f3ea875179a3ac44a4046ffd8615efe5c88f364828e7bd21b24d2d2a7f5f8ea09954f2f00056bc6d867efc22f7b82b0189de766f225101ae896
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 6875df7248f14be5a915f7b3001cd6d4a50476f84824b0118747d4ba7b2993b977cf85cfe5f9cdde8706b2d2cb4fea20c1770988405adebf09683cc966ba9e70
         
     | 
| 
         @@ -71,3 +71,10 @@ jobs: 
     | 
|
| 
       71 
71 
     | 
    
         
             
                    run: |
         
     | 
| 
       72 
72 
     | 
    
         
             
                      bundle exec rake test:foreman_remote_execution
         
     | 
| 
       73 
73 
     | 
    
         
             
                      bundle exec rake test TEST="test/unit/foreman/access_permissions_test.rb"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - name: 'Upload logs'
         
     | 
| 
      
 75 
     | 
    
         
            +
                    uses: actions/upload-artifact@v2
         
     | 
| 
      
 76 
     | 
    
         
            +
                    if: failure()
         
     | 
| 
      
 77 
     | 
    
         
            +
                    with:
         
     | 
| 
      
 78 
     | 
    
         
            +
                      name: logs
         
     | 
| 
      
 79 
     | 
    
         
            +
                      path: log/*.log
         
     | 
| 
      
 80 
     | 
    
         
            +
                      retention-days: 5
         
     | 
| 
         @@ -10,9 +10,12 @@ class UiJobWizardController < ::Api::V2::BaseController 
     | 
|
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              def template
         
     | 
| 
       12 
12 
     | 
    
         
             
                job_template = JobTemplate.authorized.find(params[:id])
         
     | 
| 
      
 13 
     | 
    
         
            +
                advanced_template_inputs, template_inputs = map_template_inputs(job_template.template_inputs_with_foreign).partition { |x| x["advanced"] }
         
     | 
| 
       13 
14 
     | 
    
         
             
                render :json => {
         
     | 
| 
       14 
15 
     | 
    
         
             
                  :job_template => job_template,
         
     | 
| 
       15 
16 
     | 
    
         
             
                  :effective_user => job_template.effective_user,
         
     | 
| 
      
 17 
     | 
    
         
            +
                  :template_inputs => template_inputs,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :advanced_template_inputs => advanced_template_inputs,
         
     | 
| 
       16 
19 
     | 
    
         
             
                }
         
     | 
| 
       17 
20 
     | 
    
         
             
              end
         
     | 
| 
       18 
21 
     | 
    
         | 
| 
         @@ -20,6 +23,10 @@ class UiJobWizardController < ::Api::V2::BaseController 
     | 
|
| 
       20 
23 
     | 
    
         
             
                nested_resource || 'job_template'
         
     | 
| 
       21 
24 
     | 
    
         
             
              end
         
     | 
| 
       22 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
              def map_template_inputs(template_inputs_with_foreign)
         
     | 
| 
      
 27 
     | 
    
         
            +
                template_inputs_with_foreign.map { |input| input.attributes.merge({:resource_type => input.resource_type&.tableize }) }
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       23 
30 
     | 
    
         
             
              def resource_class
         
     | 
| 
       24 
31 
     | 
    
         
             
                JobTemplate
         
     | 
| 
       25 
32 
     | 
    
         
             
              end
         
     | 
| 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Types
         
     | 
| 
      
 2 
     | 
    
         
            +
              class JobInvocation < BaseObject
         
     | 
| 
      
 3 
     | 
    
         
            +
                description 'A Job Invocation'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                global_id_field :id
         
     | 
| 
      
 6 
     | 
    
         
            +
                field :job_category, String
         
     | 
| 
      
 7 
     | 
    
         
            +
                field :description, String
         
     | 
| 
      
 8 
     | 
    
         
            +
                field :time_span, Integer
         
     | 
| 
      
 9 
     | 
    
         
            +
                field :start_at, GraphQL::Types::ISO8601DateTime
         
     | 
| 
      
 10 
     | 
    
         
            +
                field :status_label, String
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                belongs_to :triggering, Types::Triggering
         
     | 
| 
      
 13 
     | 
    
         
            +
                belongs_to :task, Types::Task
         
     | 
| 
      
 14 
     | 
    
         
            +
                field :recurring_logic, Types::RecurringLogic
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -7,7 +7,9 @@ module ForemanRemoteExecution 
     | 
|
| 
       7 
7 
     | 
    
         
             
                end
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                def multiple_actions
         
     | 
| 
       10 
     | 
    
         
            -
                   
     | 
| 
      
 10 
     | 
    
         
            +
                  res = super
         
     | 
| 
      
 11 
     | 
    
         
            +
                  res += [ [_('Schedule Remote Job'), new_job_invocation_path, false] ] if authorized_for(controller: :job_invocations, action: :new)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  res
         
     | 
| 
       11 
13 
     | 
    
         
             
                end
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
15 
     | 
    
         
             
                def schedule_job_multi_button(*args)
         
     | 
| 
         @@ -21,12 +23,14 @@ module ForemanRemoteExecution 
     | 
|
| 
       21 
23 
     | 
    
         
             
                end
         
     | 
| 
       22 
24 
     | 
    
         | 
| 
       23 
25 
     | 
    
         
             
                def rex_host_features(*args)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  return unless authorized_for(controller: :job_invocations, action: :create)
         
     | 
| 
       24 
27 
     | 
    
         
             
                  RemoteExecutionFeature.with_host_action_button.order(:label).map do |feature|
         
     | 
| 
       25 
28 
     | 
    
         
             
                    link_to(_('%s') % feature.name, job_invocations_path(:host_ids => [args.first.id], :feature => feature.label), :method => :post)
         
     | 
| 
       26 
29 
     | 
    
         
             
                  end
         
     | 
| 
       27 
30 
     | 
    
         
             
                end
         
     | 
| 
       28 
31 
     | 
    
         | 
| 
       29 
32 
     | 
    
         
             
                def schedule_job_button(*args)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  return unless authorized_for(controller: :job_invocations, action: :new)
         
     | 
| 
       30 
34 
     | 
    
         
             
                  link_to(_('Schedule Remote Job'), new_job_invocation_path(:host_ids => [args.first.id]), :id => :run_button, :class => 'btn btn-default')
         
     | 
| 
       31 
35 
     | 
    
         
             
                end
         
     | 
| 
       32 
36 
     | 
    
         | 
| 
         @@ -7,6 +7,10 @@ module RemoteExecutionHelper 
     | 
|
| 
       7 
7 
     | 
    
         
             
                @job_hosts_authorizer ||= Authorizer.new(User.current, :collection => @hosts)
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
              def host_tasks_authorizer
         
     | 
| 
      
 11 
     | 
    
         
            +
                @host_tasks_authorizer ||= Authorizer.new(User.current, :collection => @job_invocation.sub_tasks)
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       10 
14 
     | 
    
         
             
              def host_counter(label, count)
         
     | 
| 
       11 
15 
     | 
    
         
             
                content_tag(:div, :class => 'host_counter') do
         
     | 
| 
       12 
16 
     | 
    
         
             
                  content_tag(:div, label, :class => 'header') + content_tag(:div, count.to_s, :class => 'count')
         
     | 
| 
         @@ -36,7 +40,7 @@ module RemoteExecutionHelper 
     | 
|
| 
       36 
40 
     | 
    
         
             
                              'data-method': 'get', id: "#{host.name}-actions-rerun" } }
         
     | 
| 
       37 
41 
     | 
    
         
             
                end
         
     | 
| 
       38 
42 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks))
         
     | 
| 
      
 43 
     | 
    
         
            +
                if host_task.present? && authorized_for(hash_for_foreman_tasks_task_path(host_task).merge(auth_object: host_task, permission: :view_foreman_tasks, authorizer: host_tasks_authorizer))
         
     | 
| 
       40 
44 
     | 
    
         
             
                  links << { title: _('Host task'),
         
     | 
| 
       41 
45 
     | 
    
         
             
                    action: { href: foreman_tasks_task_path(host_task),
         
     | 
| 
       42 
46 
     | 
    
         
             
                              'data-method': 'get', id: "#{host.name}-actions-task" } }
         
     | 
| 
         @@ -109,12 +113,14 @@ module RemoteExecutionHelper 
     | 
|
| 
       109 
113 
     | 
    
         
             
                    :class => 'btn btn-danger',
         
     | 
| 
       110 
114 
     | 
    
         
             
                    :title => _('Try to cancel the job on a host'),
         
     | 
| 
       111 
115 
     | 
    
         
             
                    :disabled => !task.cancellable?,
         
     | 
| 
       112 
     | 
    
         
            -
                    :method => :post 
     | 
| 
      
 116 
     | 
    
         
            +
                    :method => :post,
         
     | 
| 
      
 117 
     | 
    
         
            +
                    :remote => true)
         
     | 
| 
       113 
118 
     | 
    
         
             
                  buttons << link_to(_('Abort Job'), abort_foreman_tasks_task_path(task),
         
     | 
| 
       114 
119 
     | 
    
         
             
                    :class => 'btn btn-danger',
         
     | 
| 
       115 
120 
     | 
    
         
             
                    :title => _('Try to abort the job on a host without waiting for its result'),
         
     | 
| 
       116 
121 
     | 
    
         
             
                    :disabled => !task.cancellable?,
         
     | 
| 
       117 
     | 
    
         
            -
                    :method => :post 
     | 
| 
      
 122 
     | 
    
         
            +
                    :method => :post,
         
     | 
| 
      
 123 
     | 
    
         
            +
                    :remote => true)
         
     | 
| 
       118 
124 
     | 
    
         
             
                end
         
     | 
| 
       119 
125 
     | 
    
         
             
                buttons
         
     | 
| 
       120 
126 
     | 
    
         
             
              end
         
     | 
| 
         @@ -72,7 +72,7 @@ module Actions 
     | 
|
| 
       72 
72 
     | 
    
         | 
| 
       73 
73 
     | 
    
         
             
                  def total_count
         
     | 
| 
       74 
74 
     | 
    
         
             
                    # For compatibility with already existing tasks
         
     | 
| 
       75 
     | 
    
         
            -
                    return output[:total_count] unless output.has_key?(:host_count) || task.pending?
         
     | 
| 
      
 75 
     | 
    
         
            +
                    return output[:total_count] || hosts.count unless output.has_key?(:host_count) || task.pending?
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
                    output[:host_count] || hosts.count
         
     | 
| 
       78 
78 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -209,7 +209,7 @@ class JobInvocationComposer 
     | 
|
| 
       209 
209 
     | 
    
         
             
                def format_datetime(datetime)
         
     | 
| 
       210 
210 
     | 
    
         
             
                  return datetime if datetime.blank?
         
     | 
| 
       211 
211 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                  Time.parse(datetime).strftime('%Y-%m-%d %H:%M')
         
     | 
| 
      
 212 
     | 
    
         
            +
                  Time.parse(datetime).utc.strftime('%Y-%m-%d %H:%M')
         
     | 
| 
       213 
213 
     | 
    
         
             
                end
         
     | 
| 
       214 
214 
     | 
    
         
             
              end
         
     | 
| 
       215 
215 
     | 
    
         | 
| 
         @@ -296,7 +296,7 @@ class JobInvocationComposer 
     | 
|
| 
       296 
296 
     | 
    
         
             
                attr_reader :feature_label, :feature, :provided_inputs
         
     | 
| 
       297 
297 
     | 
    
         | 
| 
       298 
298 
     | 
    
         
             
                def initialize(feature_label, hosts, provided_inputs = {})
         
     | 
| 
       299 
     | 
    
         
            -
                  @feature = RemoteExecutionFeature.feature(feature_label)
         
     | 
| 
      
 299 
     | 
    
         
            +
                  @feature = RemoteExecutionFeature.feature!(feature_label)
         
     | 
| 
       300 
300 
     | 
    
         
             
                  @provided_inputs = provided_inputs
         
     | 
| 
       301 
301 
     | 
    
         
             
                  translator = HostIdsTranslator.new(hosts)
         
     | 
| 
       302 
302 
     | 
    
         
             
                  @host_bookmark = translator.bookmark
         
     | 
| 
         @@ -513,7 +513,7 @@ class JobInvocationComposer 
     | 
|
| 
       513 
513 
     | 
    
         
             
              end
         
     | 
| 
       514 
514 
     | 
    
         | 
| 
       515 
515 
     | 
    
         
             
              def available_bookmarks
         
     | 
| 
       516 
     | 
    
         
            -
                Bookmark. 
     | 
| 
      
 516 
     | 
    
         
            +
                Bookmark.my_bookmarks.where(:controller => ['hosts', 'dashboard'])
         
     | 
| 
       517 
517 
     | 
    
         
             
              end
         
     | 
| 
       518 
518 
     | 
    
         | 
| 
       519 
519 
     | 
    
         
             
              def targeted_hosts
         
     | 
    
        data/app/models/job_template.rb
    CHANGED
    
    
| 
         @@ -20,7 +20,11 @@ class RemoteExecutionFeature < ApplicationRecord 
     | 
|
| 
       20 
20 
     | 
    
         
             
              end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
              def self.feature(label)
         
     | 
| 
       23 
     | 
    
         
            -
                self.find_by(label: label) 
     | 
| 
      
 23 
     | 
    
         
            +
                self.find_by(label: label)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              def self.feature!(label)
         
     | 
| 
      
 27 
     | 
    
         
            +
                feature(label) || raise(::Foreman::Exception.new(N_('Unknown remote execution feature %s'), label))
         
     | 
| 
       24 
28 
     | 
    
         
             
              end
         
     | 
| 
       25 
29 
     | 
    
         | 
| 
       26 
30 
     | 
    
         
             
              def self.register(label, name, options = {})
         
     | 
| 
         @@ -111,7 +111,7 @@ class RemoteExecutionProvider 
     | 
|
| 
       111 
111 
     | 
    
         
             
                end
         
     | 
| 
       112 
112 
     | 
    
         | 
| 
       113 
113 
     | 
    
         
             
                def proxy_action_class
         
     | 
| 
       114 
     | 
    
         
            -
                  ' 
     | 
| 
      
 114 
     | 
    
         
            +
                  'Proxy::RemoteExecution::Ssh::Actions::RunScript'
         
     | 
| 
       115 
115 
     | 
    
         
             
                end
         
     | 
| 
       116 
116 
     | 
    
         | 
| 
       117 
117 
     | 
    
         
             
                # Return a specific proxy selector to use for running a given template
         
     | 
| 
         @@ -16,8 +16,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       16 
16 
     | 
    
         
             
                              'management functionality with remote management functionality.'
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
              s.files = `git ls-files`.split("\n").reject do |file|
         
     | 
| 
       19 
     | 
    
         
            -
                file.start_with?('scripts' 
     | 
| 
       20 
     | 
    
         
            -
                  file == 'foreman_remote_execution_core.gemspec'
         
     | 
| 
      
 19 
     | 
    
         
            +
                file.start_with?('scripts')
         
     | 
| 
       21 
20 
     | 
    
         
             
              end
         
     | 
| 
       22 
21 
     | 
    
         | 
| 
       23 
22 
     | 
    
         
             
              s.test_files =       `git ls-files test`.split("\n")
         
     | 
| 
         @@ -25,8 +24,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       25 
24 
     | 
    
         | 
| 
       26 
25 
     | 
    
         
             
              s.add_dependency 'deface'
         
     | 
| 
       27 
26 
     | 
    
         
             
              s.add_dependency 'dynflow', '>= 1.0.2', '< 2.0.0'
         
     | 
| 
       28 
     | 
    
         
            -
              s.add_dependency ' 
     | 
| 
       29 
     | 
    
         
            -
              s.add_dependency 'foreman-tasks', '>= 4.1.0'
         
     | 
| 
      
 27 
     | 
    
         
            +
              s.add_dependency 'foreman-tasks', '>= 5.0.0'
         
     | 
| 
       30 
28 
     | 
    
         | 
| 
       31 
29 
     | 
    
         
             
              s.add_development_dependency 'factory_bot_rails', '~> 4.8.0'
         
     | 
| 
       32 
30 
     | 
    
         
             
              s.add_development_dependency 'rdoc'
         
     | 
| 
         @@ -152,6 +152,9 @@ module ForemanRemoteExecution 
     | 
|
| 
       152 
152 
     | 
    
         
             
                      ctx.permit :execution
         
     | 
| 
       153 
153 
     | 
    
         
             
                    end
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
                    register_graphql_query_field :job_invocations, '::Types::JobInvocation', :collection_field
         
     | 
| 
      
 156 
     | 
    
         
            +
                    register_graphql_query_field :job_invocation, '::Types::JobInvocation', :record_field
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
       155 
158 
     | 
    
         
             
                    extend_template_helpers ForemanRemoteExecution::RendererMethods
         
     | 
| 
       156 
159 
     | 
    
         | 
| 
       157 
160 
     | 
    
         
             
                    extend_rabl_template 'api/v2/smart_proxies/main', 'api/v2/smart_proxies/pubkey'
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Queries
         
     | 
| 
      
 4 
     | 
    
         
            +
              class JobInvocationQueryTest < GraphQLQueryTestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
                let(:query) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  <<-GRAPHQL
         
     | 
| 
      
 7 
     | 
    
         
            +
                  query (
         
     | 
| 
      
 8 
     | 
    
         
            +
                    $id: String!
         
     | 
| 
      
 9 
     | 
    
         
            +
                  ) {
         
     | 
| 
      
 10 
     | 
    
         
            +
                    jobInvocation(id: $id) {
         
     | 
| 
      
 11 
     | 
    
         
            +
                      id
         
     | 
| 
      
 12 
     | 
    
         
            +
                      jobCategory
         
     | 
| 
      
 13 
     | 
    
         
            +
                    }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  GRAPHQL
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                let(:job_invocation) { FactoryBot.create(:job_invocation) }
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                let(:global_id) { Foreman::GlobalId.for(job_invocation) }
         
     | 
| 
      
 21 
     | 
    
         
            +
                let(:variables) { { id: global_id } }
         
     | 
| 
      
 22 
     | 
    
         
            +
                let(:data) { result['data']['jobInvocation'] }
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                test 'fetching job invocation attributes' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  assert_empty result['errors']
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  assert_equal global_id, data['id']
         
     | 
| 
      
 28 
     | 
    
         
            +
                  assert_equal job_invocation.job_category, data['jobCategory']
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_plugin_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Queries
         
     | 
| 
      
 4 
     | 
    
         
            +
              class JobInvocationsQueryTest < GraphQLQueryTestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
                let(:query) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  <<-GRAPHQL
         
     | 
| 
      
 7 
     | 
    
         
            +
                  query {
         
     | 
| 
      
 8 
     | 
    
         
            +
                    jobInvocations {
         
     | 
| 
      
 9 
     | 
    
         
            +
                      totalCount
         
     | 
| 
      
 10 
     | 
    
         
            +
                      nodes {
         
     | 
| 
      
 11 
     | 
    
         
            +
                        id
         
     | 
| 
      
 12 
     | 
    
         
            +
                        jobCategory
         
     | 
| 
      
 13 
     | 
    
         
            +
                      }
         
     | 
| 
      
 14 
     | 
    
         
            +
                    }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  }
         
     | 
| 
      
 16 
     | 
    
         
            +
                  GRAPHQL
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                let(:data) { result['data']['jobInvocations'] }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                setup do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  FactoryBot.create_list(:job_invocation, 2)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                test 'should fetch job invocations' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  assert_empty result['errors']
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                  expected_count = JobInvocation.count
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  assert_not_equal 0, expected_count
         
     | 
| 
      
 31 
     | 
    
         
            +
                  assert_equal expected_count, data['totalCount']
         
     | 
| 
      
 32 
     | 
    
         
            +
                  assert_equal expected_count, data['nodes'].count
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -131,23 +131,23 @@ class ForemanRemoteExecutionHostExtensionsTest < ActiveSupport::TestCase 
     | 
|
| 
       131 
131 
     | 
    
         
             
                end
         
     | 
| 
       132 
132 
     | 
    
         | 
| 
       133 
133 
     | 
    
         
             
                context 'fallback strategy' do
         
     | 
| 
       134 
     | 
    
         
            -
                  let(:host) { FactoryBot.build(:host, : 
     | 
| 
      
 134 
     | 
    
         
            +
                  let(:host) { FactoryBot.build(:host, :with_tftp_subnet) }
         
     | 
| 
       135 
135 
     | 
    
         | 
| 
       136 
136 
     | 
    
         
             
                  context 'enabled' do
         
     | 
| 
       137 
137 
     | 
    
         
             
                    before do
         
     | 
| 
       138 
138 
     | 
    
         
             
                      Setting[:remote_execution_fallback_proxy] = true
         
     | 
| 
       139 
     | 
    
         
            -
                      host. 
     | 
| 
      
 139 
     | 
    
         
            +
                      host.subnet.tftp.features << FactoryBot.create(:feature, :ssh)
         
     | 
| 
       140 
140 
     | 
    
         
             
                    end
         
     | 
| 
       141 
141 
     | 
    
         | 
| 
       142 
142 
     | 
    
         
             
                    it 'returns a fallback proxy' do
         
     | 
| 
       143 
     | 
    
         
            -
                      host.remote_execution_proxies(provider)[:fallback].must_include host. 
     | 
| 
      
 143 
     | 
    
         
            +
                      host.remote_execution_proxies(provider)[:fallback].must_include host.subnet.tftp
         
     | 
| 
       144 
144 
     | 
    
         
             
                    end
         
     | 
| 
       145 
145 
     | 
    
         
             
                  end
         
     | 
| 
       146 
146 
     | 
    
         | 
| 
       147 
147 
     | 
    
         
             
                  context 'disabled' do
         
     | 
| 
       148 
148 
     | 
    
         
             
                    before do
         
     | 
| 
       149 
149 
     | 
    
         
             
                      Setting[:remote_execution_fallback_proxy] = false
         
     | 
| 
       150 
     | 
    
         
            -
                      host. 
     | 
| 
      
 150 
     | 
    
         
            +
                      host.subnet.tftp.features << FactoryBot.create(:feature, :ssh)
         
     | 
| 
       151 
151 
     | 
    
         
             
                    end
         
     | 
| 
       152 
152 
     | 
    
         | 
| 
       153 
153 
     | 
    
         
             
                    it 'returns no proxy' do
         
     | 
| 
         @@ -446,8 +446,7 @@ class InputTemplateRendererTest < ActiveSupport::TestCase 
     | 
|
| 
       446 
446 
     | 
    
         
             
                      before { User.current = FactoryBot.build(:user, :admin) }
         
     | 
| 
       447 
447 
     | 
    
         
             
                      after { User.current = nil }
         
     | 
| 
       448 
448 
     | 
    
         | 
| 
       449 
     | 
    
         
            -
                       
     | 
| 
       450 
     | 
    
         
            -
                      before { renderer.host = FactoryBot.create(:host, :environment => environment) }
         
     | 
| 
      
 449 
     | 
    
         
            +
                      before { renderer.host = FactoryBot.create(:host) }
         
     | 
| 
       451 
450 
     | 
    
         | 
| 
       452 
451 
     | 
    
         
             
                      describe 'rendering' do
         
     | 
| 
       453 
452 
     | 
    
         
             
                        it 'can\'t render the content without host since we don\'t have variable value in classification' do
         
     | 
| 
         @@ -497,91 +496,4 @@ class InputTemplateRendererTest < ActiveSupport::TestCase 
     | 
|
| 
       497 
496 
     | 
    
         
             
                  end
         
     | 
| 
       498 
497 
     | 
    
         
             
                end
         
     | 
| 
       499 
498 
     | 
    
         
             
              end
         
     | 
| 
       500 
     | 
    
         
            -
             
     | 
| 
       501 
     | 
    
         
            -
              context 'renderer for template with puppet parameter input used' do
         
     | 
| 
       502 
     | 
    
         
            -
                let(:template) { FactoryBot.build(:job_template, :template => 'echo "This is WebServer with nginx <%= input("nginx_version") -%>" > /etc/motd') }
         
     | 
| 
       503 
     | 
    
         
            -
                let(:renderer) { InputTemplateRenderer.new(template) }
         
     | 
| 
       504 
     | 
    
         
            -
             
     | 
| 
       505 
     | 
    
         
            -
                context 'with matching input defined' do
         
     | 
| 
       506 
     | 
    
         
            -
                  before do
         
     | 
| 
       507 
     | 
    
         
            -
                    renderer.template.template_inputs<< FactoryBot.build(:template_input,
         
     | 
| 
       508 
     | 
    
         
            -
                      :name => 'nginx_version',
         
     | 
| 
       509 
     | 
    
         
            -
                      :input_type => 'puppet_parameter',
         
     | 
| 
       510 
     | 
    
         
            -
                      :puppet_parameter_name => 'version',
         
     | 
| 
       511 
     | 
    
         
            -
                      :puppet_class_name => 'nginx')
         
     | 
| 
       512 
     | 
    
         
            -
                  end
         
     | 
| 
       513 
     | 
    
         
            -
                  let(:result) { renderer.render }
         
     | 
| 
       514 
     | 
    
         
            -
             
     | 
| 
       515 
     | 
    
         
            -
                  describe 'rendering' do
         
     | 
| 
       516 
     | 
    
         
            -
                    it 'can\'t render the content without host since we don\'t have host so no classification' do
         
     | 
| 
       517 
     | 
    
         
            -
                      assert_not result
         
     | 
| 
       518 
     | 
    
         
            -
                    end
         
     | 
| 
       519 
     | 
    
         
            -
             
     | 
| 
       520 
     | 
    
         
            -
                    it 'registers an error' do
         
     | 
| 
       521 
     | 
    
         
            -
                      result # let is lazy
         
     | 
| 
       522 
     | 
    
         
            -
                      _(renderer.error_message).wont_be_nil
         
     | 
| 
       523 
     | 
    
         
            -
                      _(renderer.error_message).wont_be_empty
         
     | 
| 
       524 
     | 
    
         
            -
                    end
         
     | 
| 
       525 
     | 
    
         
            -
             
     | 
| 
       526 
     | 
    
         
            -
                    context 'with host specified' do
         
     | 
| 
       527 
     | 
    
         
            -
                      let(:environment) { FactoryBot.create(:environment) }
         
     | 
| 
       528 
     | 
    
         
            -
                      before { renderer.host = FactoryBot.create(:host, :environment => environment) }
         
     | 
| 
       529 
     | 
    
         
            -
             
     | 
| 
       530 
     | 
    
         
            -
                      describe 'rendering' do
         
     | 
| 
       531 
     | 
    
         
            -
                        it 'can\'t render the content without host since we don\'t have puppet parameter in classification' do
         
     | 
| 
       532 
     | 
    
         
            -
                          assert_not result
         
     | 
| 
       533 
     | 
    
         
            -
                        end
         
     | 
| 
       534 
     | 
    
         
            -
             
     | 
| 
       535 
     | 
    
         
            -
                        it 'registers an error' do
         
     | 
| 
       536 
     | 
    
         
            -
                          result # let is lazy
         
     | 
| 
       537 
     | 
    
         
            -
                          _(renderer.error_message).wont_be_nil
         
     | 
| 
       538 
     | 
    
         
            -
                          _(renderer.error_message).wont_be_empty
         
     | 
| 
       539 
     | 
    
         
            -
                        end
         
     | 
| 
       540 
     | 
    
         
            -
                      end
         
     | 
| 
       541 
     | 
    
         
            -
             
     | 
| 
       542 
     | 
    
         
            -
                      describe 'preview' do
         
     | 
| 
       543 
     | 
    
         
            -
                        it 'should render preview' do
         
     | 
| 
       544 
     | 
    
         
            -
                          _(renderer.preview).must_equal 'echo "This is WebServer with nginx $PUPPET_PARAMETER_INPUT[nginx_version]" > /etc/motd'
         
     | 
| 
       545 
     | 
    
         
            -
                        end
         
     | 
| 
       546 
     | 
    
         
            -
                      end
         
     | 
| 
       547 
     | 
    
         
            -
             
     | 
| 
       548 
     | 
    
         
            -
                      context 'with existing puppet parameter with matching override' do
         
     | 
| 
       549 
     | 
    
         
            -
                        let(:puppet_class) do
         
     | 
| 
       550 
     | 
    
         
            -
                          puppetclass = FactoryBot.create(:puppetclass, :environments => [environment], :name => 'nginx')
         
     | 
| 
       551 
     | 
    
         
            -
                          puppetclass.update_attribute(:hosts, [renderer.host])
         
     | 
| 
       552 
     | 
    
         
            -
                          puppetclass
         
     | 
| 
       553 
     | 
    
         
            -
                        end
         
     | 
| 
       554 
     | 
    
         
            -
                        let(:lookup_key) do
         
     | 
| 
       555 
     | 
    
         
            -
                          FactoryBot.create(:puppetclass_lookup_key, :as_smart_class_param,
         
     | 
| 
       556 
     | 
    
         
            -
                            :key => 'version',
         
     | 
| 
       557 
     | 
    
         
            -
                            :puppetclass => puppet_class,
         
     | 
| 
       558 
     | 
    
         
            -
                            :path => 'fqdn',
         
     | 
| 
       559 
     | 
    
         
            -
                            :override => true,
         
     | 
| 
       560 
     | 
    
         
            -
                            :overrides => {"fqdn=#{renderer.host.fqdn}" => '1.4.7'})
         
     | 
| 
       561 
     | 
    
         
            -
                        end
         
     | 
| 
       562 
     | 
    
         
            -
             
     | 
| 
       563 
     | 
    
         
            -
                        describe 'rendering' do
         
     | 
| 
       564 
     | 
    
         
            -
                          it 'renders the value from puppet parameter' do
         
     | 
| 
       565 
     | 
    
         
            -
                            lookup_key
         
     | 
| 
       566 
     | 
    
         
            -
                            _(result).must_equal 'echo "This is WebServer with nginx 1.4.7" > /etc/motd'
         
     | 
| 
       567 
     | 
    
         
            -
                          end
         
     | 
| 
       568 
     | 
    
         
            -
                        end
         
     | 
| 
       569 
     | 
    
         
            -
             
     | 
| 
       570 
     | 
    
         
            -
                        describe 'preview' do
         
     | 
| 
       571 
     | 
    
         
            -
                          it 'should render preview' do
         
     | 
| 
       572 
     | 
    
         
            -
                            lookup_key
         
     | 
| 
       573 
     | 
    
         
            -
                            _(renderer.preview).must_equal 'echo "This is WebServer with nginx 1.4.7" > /etc/motd'
         
     | 
| 
       574 
     | 
    
         
            -
                          end
         
     | 
| 
       575 
     | 
    
         
            -
                        end
         
     | 
| 
       576 
     | 
    
         
            -
                      end
         
     | 
| 
       577 
     | 
    
         
            -
                    end
         
     | 
| 
       578 
     | 
    
         
            -
             
     | 
| 
       579 
     | 
    
         
            -
                    describe 'preview' do
         
     | 
| 
       580 
     | 
    
         
            -
                      it 'should render preview' do
         
     | 
| 
       581 
     | 
    
         
            -
                        _(renderer.preview).must_equal 'echo "This is WebServer with nginx $PUPPET_PARAMETER_INPUT[nginx_version]" > /etc/motd'
         
     | 
| 
       582 
     | 
    
         
            -
                      end
         
     | 
| 
       583 
     | 
    
         
            -
                    end
         
     | 
| 
       584 
     | 
    
         
            -
                  end
         
     | 
| 
       585 
     | 
    
         
            -
                end
         
     | 
| 
       586 
     | 
    
         
            -
              end
         
     | 
| 
       587 
499 
     | 
    
         
             
            end
         
     |