foreman_remote_execution 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +7 -0
  4. data/.rubocop_todo.yml +16 -5
  5. data/.tx/config +1 -1
  6. data/app/assets/javascripts/template_invocation.js +14 -1
  7. data/app/assets/stylesheets/job_invocations.css.scss +0 -13
  8. data/app/assets/stylesheets/template_invocation.css.scss +7 -13
  9. data/app/controllers/api/v2/foreign_input_sets_controller.rb +1 -1
  10. data/app/controllers/api/v2/job_invocations_controller.rb +12 -18
  11. data/app/controllers/api/v2/remote_execution_features_controller.rb +38 -0
  12. data/app/controllers/api/v2/template_inputs_controller.rb +1 -0
  13. data/app/controllers/job_invocations_controller.rb +3 -13
  14. data/app/controllers/job_templates_controller.rb +1 -1
  15. data/app/controllers/remote_execution_features_controller.rb +19 -0
  16. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -22
  17. data/app/helpers/remote_execution_helper.rb +30 -12
  18. data/app/lib/actions/remote_execution/helpers/live_output.rb +2 -2
  19. data/app/lib/actions/remote_execution/run_host_job.rb +7 -4
  20. data/app/lib/actions/remote_execution/run_hosts_job.rb +14 -0
  21. data/app/lib/actions/remote_execution/run_proxy_command.rb +2 -2
  22. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +5 -4
  23. data/app/models/concerns/foreman_remote_execution/subnet_extensions.rb +1 -0
  24. data/app/models/input_template_renderer.rb +14 -3
  25. data/app/models/job_invocation.rb +6 -15
  26. data/app/models/job_invocation_composer.rb +131 -21
  27. data/app/models/job_template.rb +77 -22
  28. data/app/models/job_template_effective_user.rb +0 -2
  29. data/app/models/remote_execution_feature.rb +34 -0
  30. data/app/models/setting/remote_execution.rb +4 -1
  31. data/app/models/targeting.rb +2 -2
  32. data/app/models/template_input.rb +17 -13
  33. data/app/views/api/v2/remote_execution_features/base.json.rabl +3 -0
  34. data/app/views/api/v2/remote_execution_features/index.json.rabl +3 -0
  35. data/app/views/api/v2/remote_execution_features/main.json.rabl +3 -0
  36. data/app/views/api/v2/remote_execution_features/show.json.rabl +3 -0
  37. data/app/views/job_invocations/_form.html.erb +51 -40
  38. data/app/views/job_invocations/_preview_hosts_list.html.erb +1 -1
  39. data/app/views/job_invocations/_tab_hosts.html.erb +6 -3
  40. data/app/views/job_invocations/index.html.erb +11 -11
  41. data/app/views/job_templates/_custom_tabs.html.erb +4 -4
  42. data/app/views/job_templates/index.html.erb +5 -5
  43. data/app/views/overrides/nics/_execution_interface.html.erb +9 -1
  44. data/app/views/remote_execution_features/_form.html.erb +24 -0
  45. data/app/views/remote_execution_features/index.html.erb +21 -0
  46. data/app/views/remote_execution_features/show.html.erb +3 -0
  47. data/app/views/template_inputs/_form.html.erb +1 -0
  48. data/app/views/template_inputs/_invocation_form.html.erb +7 -0
  49. data/app/views/templates/package_action.erb +17 -5
  50. data/app/views/templates/power_action.erb +22 -0
  51. data/app/views/templates/puppet_run_once.erb +1 -1
  52. data/config/routes.rb +4 -0
  53. data/db/migrate/20160113162007_expand_all_template_invocations.rb +1 -1
  54. data/db/migrate/20160118124600_create_remote_execution_features.rb +14 -0
  55. data/db/migrate/20160125155108_make_job_template_name_unique.rb +12 -0
  56. data/db/migrate/20160127134031_add_advanced_to_template_input.rb +11 -0
  57. data/db/migrate/20160127162711_reword_puppet_template_description.rb +9 -0
  58. data/db/migrate/20160203104056_add_concurrency_options_to_job_invocation.rb +6 -0
  59. data/db/seeds.d/70-job_templates.rb +2 -1
  60. data/doc/plugins/div_tag.rb +1 -1
  61. data/doc/plugins/plantuml.rb +1 -1
  62. data/doc/plugins/tags.rb +7 -8
  63. data/doc/plugins/toc.rb +0 -1
  64. data/foreman_remote_execution.gemspec +1 -1
  65. data/lib/foreman_remote_execution/engine.rb +10 -2
  66. data/lib/foreman_remote_execution/version.rb +1 -1
  67. data/locale/action_names.rb +8 -0
  68. data/locale/en/foreman_remote_execution.po +767 -11
  69. data/locale/foreman_remote_execution.pot +1026 -8
  70. data/test/functional/api/v2/foreign_input_sets_controller_test.rb +1 -1
  71. data/test/functional/api/v2/job_invocations_controller_test.rb +0 -9
  72. data/test/functional/api/v2/job_templates_controller_test.rb +11 -11
  73. data/test/functional/api/v2/remote_execution_features_controller_test.rb +35 -0
  74. data/test/functional/api/v2/template_inputs_controller_test.rb +1 -1
  75. data/test/unit/actions/run_hosts_job_test.rb +48 -7
  76. data/test/unit/actions/run_proxy_command_test.rb +1 -1
  77. data/test/unit/concerns/host_extensions_test.rb +11 -0
  78. data/test/unit/input_template_renderer_test.rb +4 -4
  79. data/test/unit/job_invocation_composer_test.rb +52 -2
  80. data/test/unit/job_invocation_test.rb +1 -1
  81. data/test/unit/job_template_test.rb +126 -3
  82. data/test/unit/remote_execution_feature_test.rb +42 -0
  83. data/test/unit/targeting_test.rb +4 -4
  84. metadata +26 -7
  85. data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +0 -31
  86. data/app/views/unattended/snippets/_remote_execution_ssh_keys.erb +0 -18
  87. data/db/seeds.d/80-provision_templates.rb +0 -21
@@ -11,10 +11,10 @@
11
11
 
12
12
  <%= text_f f, :description_format,
13
13
  :disabled => @template.locked?,
14
- :help_inline => popover(_('Explanation'), _('This template is used to generate the description.
15
- Input values can be used using the syntax %{package}.
16
- You may also include the job category and template
17
- name using %{job_category} and %{template_name}.')) %>
14
+ :help_inline => popover(_('Explanation'), _('This template is used to generate the description. ' +
15
+ 'Input values can be used using the syntax %{package}. ' +
16
+ 'You may also include the job category and template ' +
17
+ 'name using %{job_category} and %{template_name}.')) %>
18
18
 
19
19
  <%= select_f f, :provider_type, providers_options, :first, :last, :disabled => @template.locked? %>
20
20
 
@@ -7,13 +7,13 @@
7
7
  display_link_if_authorized(_("New Job Template"),
8
8
  hash_for_new_job_template_path)) %>
9
9
 
10
- <table class="table table-bordered table-striped table-two-pane">
10
+ <table class="table table-bordered table-striped table-two-pane table-fixed">
11
11
  <thead>
12
12
  <tr>
13
- <th><%= sort :name, :as => s_("JobTemplate|Name") %></th>
14
- <th><%= sort :snippet, :as => s_("JobTemplate|Snippet") %></th>
15
- <th><%= sort :locked, :as => s_("JobTemplate|Locked"), :default => "DESC" %></th>
16
- <th></th>
13
+ <th class="col-md-6"><%= sort :name, :as => s_("JobTemplate|Name") %></th>
14
+ <th class="col-md-1"><%= sort :snippet, :as => s_("JobTemplate|Snippet") %></th>
15
+ <th class="col-md-1"><%= sort :locked, :as => s_("JobTemplate|Locked"), :default => "DESC" %></th>
16
+ <th class="col-md-1"><%= _('Actions') %></th>
17
17
  </tr>
18
18
  </thead>
19
19
  <tbody>
@@ -1 +1,9 @@
1
- <%= checkbox_f f, :execution, :help_inline => _("The execution interface is used for remote execution"), :class => :interface_execution %>
1
+ <%= checkbox_f(
2
+ f,
3
+ :execution,
4
+ :help_inline => popover(
5
+ '', _("The execution interface is used for remote execution"),
6
+ :rel => 'popover-modal'),
7
+ :label_size => 'col-md-3',
8
+ :label => _('Remote execution'),
9
+ :class => :interface_execution) %>
@@ -0,0 +1,24 @@
1
+ <%= form_for @remote_execution_feature do |f| %>
2
+ <div class="row">
3
+ <%= field(f, :name) { @remote_execution_feature.name } %>
4
+ </div>
5
+ <div class="row">
6
+ <%= field(f, :label) { @remote_execution_feature.label } %>
7
+ </div>
8
+ <div class="row">
9
+ <%= field(f, :description) { @remote_execution_feature.description } %>
10
+ </div>
11
+ <div class="row">
12
+ <%= field(f, :provided_inputs) { @remote_execution_feature.provided_inputs } %>
13
+ </div>
14
+ <div class="row">
15
+ <% job_templates = JobTemplate.authorized(:view_job_templates) %>
16
+ <% if @remote_execution_feature.job_template_id.present? && job_templates.where(:id => @remote_execution_feature.job_template_id).empty? %>
17
+ <div class="alert alert-warning" role="alert">
18
+ <%= _("You are not allowed to see the currently assigned template. Saving the form now would unassign the template.") %>
19
+ </div>
20
+ <% end %>
21
+ <%= selectable_f f, :job_template_id, job_templates.map { |t| [ t.name, t.id ] }, { :include_blank => true }, :class => 'input_type_selector' %>
22
+ </div>
23
+ <%= submit_or_cancel f %>
24
+ <% end %>
@@ -0,0 +1,21 @@
1
+ <% title _('Remote Execution Features') %>
2
+
3
+ <table class="table table-bordered table-striped table-condensed">
4
+ <thead>
5
+ <tr>
6
+ <th><%= sort :label, :as => _('Label') %></th>
7
+ <th><%= sort :name, :as => _('Name') %></th>
8
+ <th><%= sort :description, :as => _('Description') %></th>
9
+ </tr>
10
+ </thead>
11
+
12
+ <tbody>
13
+ <% @remote_execution_features.each do |feature| %>
14
+ <tr>
15
+ <td><%= link_to_if_authorized feature.label, hash_for_remote_execution_feature_path(feature).merge(:auth_object => feature, :permission => :edit_remote_execution_features) %></td>
16
+ <td><%= feature.name %></td>
17
+ <td><%= feature.description %></td>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
21
+ </table>
@@ -0,0 +1,3 @@
1
+ <% title _("Edit Remote Execution Feature") %>
2
+
3
+ <%= render :partial => 'form' %>
@@ -15,6 +15,7 @@
15
15
  <%= text_f f, :puppet_parameter_name, :class => 'puppet_parameter_input_type', :required => true, :disabled => @template.locked? %>
16
16
  </div>
17
17
  <div class="user_input_type custom_input_type_fields" style="<%= (f.object.user_template_input? || f.object.new_record?) ? '' : 'display:none' %>">
18
+ <%= checkbox_f f, :advanced, :disabled => @template.locked? %>
18
19
  <%= textarea_f f, :options, :rows => 3, :class => 'user_input_type', :help_inline => _("A list of options the user can select from. If not provided, the user will be given a free-form field"),
19
20
  :disabled => @template.locked? %>
20
21
  </div>
@@ -0,0 +1,7 @@
1
+ <%= input_values_fields.fields_for input.id.to_s, composer.template_invocation_input_value_for(job_template, input) do |input_fields| %>
2
+ <% unless input.options.blank? %>
3
+ <%= selectable_f input_fields, :value, input.options_array, {:include_blank => !input.required}, :require => input.required, :label => input.name, :help_inline => input.description, :id => input.name, :onchange => "regenerate_description(this);" %>
4
+ <% else %>
5
+ <%= textarea_f input_fields, :value, :label => input.name, :help_inline => input.description, :required => input.required, :rows => 2, :onchange => "regenerate_description(this);", :id => input.name %>
6
+ <% end %>
7
+ <% end %>
@@ -9,11 +9,12 @@ template_inputs:
9
9
  description: A script to run prior to the package action
10
10
  input_type: user
11
11
  required: false
12
+ advanced: true
12
13
  - name: action
13
14
  description: 'The package action: install, update, or remove'
14
15
  input_type: user
15
16
  required: true
16
- options: "install\nupdate\nremove"
17
+ options: "install\nupdate\nremove\ngroup install\ngroup remove"
17
18
  - name: package
18
19
  description: The name of the package, if any
19
20
  input_type: user
@@ -22,9 +23,20 @@ template_inputs:
22
23
  description: A script to run after the package action
23
24
  input_type: user
24
25
  required: false
26
+ advanced: true
25
27
  %>
26
28
 
27
- die() {
29
+ <%
30
+ supported_families = ['Redhat', 'Debian']
31
+ render_error(N_('Unsupported or no operating system found for this host.')) unless @host.operatingsystem && supported_families.include?(@host.operatingsystem.family)
32
+ %>
33
+
34
+ # Helper function that exits with a particular message and code.
35
+ #
36
+ # Usage:
37
+ # exit_with_message "Could not do a thing" 2
38
+ #
39
+ function exit_with_message() {
28
40
  echo "${1}, exiting..."
29
41
  exit $2
30
42
  }
@@ -33,7 +45,7 @@ die() {
33
45
  # Pre Script
34
46
  <%= input("pre_script") %>
35
47
  RETVAL=$?
36
- [ $RETVAL -eq 0 ] || die "Pre script failed" $RETVAL
48
+ [ $RETVAL -eq 0 ] || exit_with_message "Pre script failed" $RETVAL
37
49
  <% end -%>
38
50
 
39
51
  # Action
@@ -43,11 +55,11 @@ die() {
43
55
  apt-get -y <%= input("action") %> <%= input("package") %>
44
56
  <% end -%>
45
57
  RETVAL=$?
46
- [ $RETVAL -eq 0 ] || die "Package action failed" $RETVAL
58
+ [ $RETVAL -eq 0 ] || exit_with_message "Package action failed" $RETVAL
47
59
 
48
60
  <% unless input("post_script").blank? -%>
49
61
  # Post Script
50
62
  <%= input("post_script") %>
51
63
  RETVAL=$?
52
- [ $RETVAL -eq 0 ] || die "Post script failed" $RETVAL
64
+ [ $RETVAL -eq 0 ] || exit_with_message "Post script failed" $RETVAL
53
65
  <% end -%>
@@ -0,0 +1,22 @@
1
+ <%#
2
+ kind: job_template
3
+ name: Power Action - SSH Default
4
+ job_category: Power
5
+ description_format: '%{action} host'
6
+ provider_type: SSH
7
+ template_inputs:
8
+ - name: action
9
+ description: Action to perform on the service
10
+ input_type: user
11
+ options: "restart\nshutdown"
12
+ required: true
13
+ %>
14
+
15
+ echo <%= input('action') %> host && sleep 3
16
+ <%= case input('action')
17
+ when 'restart'
18
+ 'reboot'
19
+ else
20
+ 'shutdown -h now'
21
+ end %>
22
+
@@ -2,7 +2,7 @@
2
2
  kind: job_template
3
3
  name: Puppet Run Once - SSH Default
4
4
  job_category: Puppet
5
- description_format: '%{job_category} with "%{puppet_options}"'
5
+ description_format: 'Run Puppet once with "%{puppet_options}"'
6
6
  provider_type: SSH
7
7
  template_inputs:
8
8
  - name: puppet_options
@@ -25,6 +25,8 @@ Rails.application.routes.draw do
25
25
  end
26
26
  end
27
27
 
28
+ resources :remote_execution_features, :only => [:show, :index, :update]
29
+
28
30
  # index is needed so the auto_complete_search can be constructed, otherwise autocompletion in filter does not work
29
31
  resources :template_invocations, :only => [:show, :index] do
30
32
  collection do
@@ -53,6 +55,8 @@ Rails.application.routes.draw do
53
55
  resources :template_inputs, :only => [:index, :show, :create, :destroy, :update]
54
56
  resources :foreign_input_sets, :only => [:index, :show, :create, :destroy, :update]
55
57
  end
58
+
59
+ resources :remote_execution_features, :only => [:show, :index, :update]
56
60
  end
57
61
  end
58
62
  end
@@ -18,7 +18,7 @@ class ExpandAllTemplateInvocations < ActiveRecord::Migration
18
18
  job_invocation.pattern_template_invocations.each do |pattern_template_invocation|
19
19
  job_invocation.targeting.hosts.each do |host|
20
20
  task = job_invocation.sub_tasks.find do |sub_task|
21
- sub_task.locks.find { |lock| lock.resource_type == 'Host::Managed' && lock.resource_id == host.id && lock.name == 'link_resource'}.present?
21
+ sub_task.locks.find { |lock| lock.resource_type == 'Host::Managed' && lock.resource_id == host.id && lock.name == 'link_resource' }.present?
22
22
  end
23
23
  next if task.nil? # job invocations with static targeting that failed too early
24
24
 
@@ -0,0 +1,14 @@
1
+ class CreateRemoteExecutionFeatures < ActiveRecord::Migration
2
+ def change
3
+ create_table :remote_execution_features do |t|
4
+ t.string :label, :index => true, :null => false
5
+ t.string :name, :null => false
6
+ t.string :description
7
+ t.text :provided_inputs
8
+ t.integer :job_template_id
9
+ end
10
+ add_index :remote_execution_features, :label
11
+ add_index :remote_execution_features, :job_template_id
12
+ add_foreign_key :remote_execution_features, :templates, :column => :job_template_id
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ class MakeJobTemplateNameUnique < ActiveRecord::Migration
2
+ def up
3
+ duplicates = JobTemplate.unscoped.group(:name).count.delete_if { |_name, value| value == 1 }
4
+ duplicates.each_key do |duplicated_name|
5
+ templates = JobTemplate.where(:name => duplicated_name)
6
+ templates.each_with_index do |template, index|
7
+ new_name = JobTemplate.exists?(:name => "#{template.name}-#{index}") ? "#{template.name}-#{index}-#{SecureRandom.hex(2)}" : "#{template.name}-#{index}"
8
+ template.update_attribute(:name, new_name)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class AddAdvancedToTemplateInput < ActiveRecord::Migration
2
+ def up
3
+ add_column :template_inputs, :advanced, :boolean, :default => false, :null => false
4
+ template = JobTemplate.find_by_name('Package Action - SSH Default')
5
+ TemplateInput.where(:name => ['pre_script', 'post_script'], :template_id => template.try(:id)).update_all(:advanced => true)
6
+ end
7
+
8
+ def down
9
+ remove_column :template_inputs, :advanced
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class RewordPuppetTemplateDescription < ActiveRecord::Migration
2
+ def up
3
+ JobTemplate.where(:name => 'Puppet Run Once - SSH Default').update_all(:description_format => 'Run Puppet once with "%{puppet_options}"')
4
+ end
5
+
6
+ def down
7
+ JobTemplate.where(:name => 'Puppet Run Once - SSH Default').update_all(:description_format => '%{job_category} with "%{puppet_options}"')
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class AddConcurrencyOptionsToJobInvocation < ActiveRecord::Migration
2
+ def change
3
+ add_column :job_invocations, :concurrency_level, :integer, :null => true
4
+ add_column :job_invocations, :time_span, :integer, :null => true
5
+ end
6
+ end
@@ -1,7 +1,8 @@
1
1
  User.as_anonymous_admin do
2
2
  JobTemplate.without_auditing do
3
3
  Dir[File.join("#{ForemanRemoteExecution::Engine.root}/app/views/templates/**/*.erb")].each do |template|
4
- JobTemplate.import(File.read(template), :default => true, :locked => true)
4
+ sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
5
+ JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
5
6
  end
6
7
  end
7
8
  end
@@ -1,7 +1,7 @@
1
1
  module Jekyll
2
2
  class DivTag < Liquid::Block
3
3
  def render(context)
4
- content = super
4
+ content = super
5
5
 
6
6
  <<-HTML.gsub(/^ +\|/, '')
7
7
  |<#{tag} class="#{@markup}">
@@ -36,7 +36,7 @@ module Jekyll
36
36
 
37
37
  site.static_files << Jekyll::StaticFile.new(site, tmproot, folder, filename)
38
38
 
39
- "<img src='" + "#{ site.baseurl }/" + folder + filename + "'>"
39
+ "<img src='#{site.baseurl}/#{folder}#{filename}>"
40
40
  end
41
41
 
42
42
  private
@@ -30,7 +30,7 @@ module Jekyll
30
30
  end
31
31
 
32
32
  def new_tag(tag, posts)
33
- self.class.types.each { |type|
33
+ self.class.types.each do |type|
34
34
  if layout = site.config["tag_#{type}_layout"]
35
35
  data = { 'layout' => layout, 'posts' => posts.sort.reverse!, 'tag' => tag, 'title' => tag }
36
36
 
@@ -43,10 +43,10 @@ module Jekyll
43
43
  page_name = "#{pretty? ? 'index' : name}#{site.layouts[data['layout']].ext}"
44
44
 
45
45
  site.pages << TagPage.new(
46
- site, site.source, tag_dir, page_name, data
46
+ site, site.source, tag_dir, page_name, data
47
47
  )
48
48
  end
49
- }
49
+ end
50
50
  end
51
51
 
52
52
  def add_tag_cloud(num = 5, name = 'tag_data')
@@ -61,10 +61,9 @@ module Jekyll
61
61
  def calculate_tag_cloud(num = 5)
62
62
  range = 0
63
63
 
64
- tags = active_tags.map { |tag, posts|
64
+ tags = active_tags.map do |tag, posts|
65
65
  [tag.to_s, range < (size = posts.size) ? range = size : size]
66
- }
67
-
66
+ end
68
67
 
69
68
  range = 1..range
70
69
 
@@ -100,9 +99,9 @@ module Jekyll
100
99
  module Filters
101
100
 
102
101
  def tag_cloud(site)
103
- active_tag_data.map { |tag, set|
102
+ active_tag_data.map do |tag, set|
104
103
  tag_link(tag, tag_url(tag), :class => "set-#{set} label label-default")
105
- }.join(' ')
104
+ end.join(' ')
106
105
  end
107
106
 
108
107
  def tag_link(tag, url = tag_url(tag), html_opts = nil)
@@ -1,7 +1,6 @@
1
1
  module Jekyll
2
2
  module FancyToCFilter
3
3
  def fancytoc(input)
4
-
5
4
  converter = @context.registers[:site].converters.find { |c| c.is_a? Jekyll::Converters::Markdown }
6
5
  extensions = converter.instance_variable_get(:@parser).instance_variable_get(:@redcarpet_extensions)
7
6
  toc_generator = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC, extensions)
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.extra_rdoc_files = `git ls-files doc`.split("\n") + Dir['README*', 'LICENSE']
20
20
 
21
21
  s.add_dependency 'deface'
22
- s.add_dependency 'dynflow', '~> 0.8.8'
22
+ s.add_dependency 'dynflow', '~> 0.8.10'
23
23
  s.add_dependency 'foreman-tasks', '~> 0.7.11'
24
24
 
25
25
  s.add_development_dependency 'rubocop'
@@ -29,7 +29,7 @@ module ForemanRemoteExecution
29
29
 
30
30
  initializer 'foreman_remote_execution.register_plugin', after: :finisher_hook do |_app|
31
31
  Foreman::Plugin.register :foreman_remote_execution do
32
- requires_foreman '>= 1.10'
32
+ requires_foreman '>= 1.11'
33
33
 
34
34
  apipie_documented_controllers ["#{ForemanRemoteExecution::Engine.root}/app/controllers/api/v2/*.rb"]
35
35
 
@@ -45,6 +45,8 @@ module ForemanRemoteExecution
45
45
  :'api/v2/job_templates' => [:update],
46
46
  :'api/v2/template_inputs' => [:create, :update, :destroy],
47
47
  :'api/v2/foreign_input_sets' => [:create, :update, :destroy]}, :resource_type => 'JobTemplate'
48
+ permission :edit_remote_execution_features, { :remote_execution_features => [:index, :show, :update],
49
+ :'api/v2/remote_execution_features' => [:index, :show, :update]}, :resource_type => 'RemoteExecutionFeature'
48
50
  permission :destroy_job_templates, { :job_templates => [:destroy],
49
51
  :'api/v2/job_templates' => [:destroy] }, :resource_type => 'JobTemplate'
50
52
  permission :lock_job_templates, { :job_templates => [:lock, :unlock] }, :resource_type => 'JobTemplate'
@@ -72,7 +74,8 @@ module ForemanRemoteExecution
72
74
  :create_job_templates,
73
75
  :lock_job_templates,
74
76
  :view_audit_logs,
75
- :filter_autocompletion_for_template_invocation
77
+ :filter_autocompletion_for_template_invocation,
78
+ :edit_remote_execution_features
76
79
  ]
77
80
 
78
81
  # Add a new role called 'Remote Execution User ' if it doesn't exist
@@ -85,6 +88,11 @@ module ForemanRemoteExecution
85
88
  caption: N_('Job templates'),
86
89
  parent: :hosts_menu,
87
90
  after: :provisioning_templates
91
+ menu :admin_menu, :remote_execution_features,
92
+ url_hash: { controller: :remote_execution_features, action: :index },
93
+ caption: N_('Remote Execution Features'),
94
+ parent: :administer_menu,
95
+ after: :bookmarks
88
96
 
89
97
  menu :top_menu, :job_invocations,
90
98
  url_hash: { controller: :job_invocations, action: :index },
@@ -1,3 +1,3 @@
1
1
  module ForemanRemoteExecution
2
- VERSION = '0.2.3'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,8 @@
1
+ # Autogenerated!
2
+ _("Create architecture")
3
+ _("Delete architecture")
4
+ _("Update architecture")
5
+ _("Import facts")
6
+ _("Import puppetclasses")
7
+ _("Action with sub plans")
8
+ _("Remote action:")