foreman_remote_execution 0.1.2 → 0.2.1

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.rubocop_todo.yml +0 -6
  4. data/app/assets/javascripts/template_input.js +5 -0
  5. data/app/assets/javascripts/template_invocation.js +44 -12
  6. data/app/controllers/api/v2/foreign_input_sets_controller.rb +80 -0
  7. data/app/controllers/api/v2/job_invocations_controller.rb +28 -14
  8. data/app/controllers/api/v2/job_templates_controller.rb +24 -20
  9. data/app/controllers/api/v2/template_inputs_controller.rb +10 -7
  10. data/app/controllers/job_invocations_controller.rb +18 -6
  11. data/app/controllers/job_templates_controller.rb +14 -4
  12. data/app/controllers/template_invocations_controller.rb +5 -3
  13. data/app/helpers/concerns/foreman_remote_execution/hosts_helper_extensions.rb +1 -1
  14. data/app/helpers/concerns/foreman_remote_execution/job_templates_extensions.rb +19 -0
  15. data/app/helpers/remote_execution_helper.rb +88 -39
  16. data/app/lib/actions/remote_execution/run_host_job.rb +11 -8
  17. data/app/lib/actions/remote_execution/run_hosts_job.rb +5 -2
  18. data/app/lib/actions/remote_execution/run_proxy_command.rb +9 -4
  19. data/app/models/concerns/foreman_remote_execution/errors_flattener.rb +2 -2
  20. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +2 -2
  21. data/app/models/concerns/foreman_remote_execution/smart_proxy_extensions.rb +1 -1
  22. data/app/models/concerns/foreman_remote_execution/template_extensions.rb +9 -1
  23. data/app/models/foreign_input_set.rb +49 -0
  24. data/app/models/host_status/execution_status.rb +50 -5
  25. data/app/models/input_template_renderer.rb +52 -7
  26. data/app/models/job_invocation.rb +89 -32
  27. data/app/models/job_invocation_composer.rb +71 -55
  28. data/app/models/job_template.rb +43 -7
  29. data/app/models/remote_execution_provider.rb +1 -1
  30. data/app/models/setting/remote_execution.rb +7 -7
  31. data/app/models/ssh_execution_provider.rb +1 -1
  32. data/app/models/targeting.rb +1 -1
  33. data/app/models/template_invocation.rb +9 -4
  34. data/app/views/api/v2/foreign_input_sets/base.json.rabl +3 -0
  35. data/app/views/api/v2/foreign_input_sets/create.json.rabl +3 -0
  36. data/app/views/api/v2/foreign_input_sets/index.json.rabl +3 -0
  37. data/app/views/api/v2/foreign_input_sets/main.json.rabl +5 -0
  38. data/app/views/api/v2/foreign_input_sets/show.json.rabl +3 -0
  39. data/app/views/api/v2/job_invocations/base.json.rabl +10 -1
  40. data/app/views/api/v2/job_invocations/main.json.rabl +14 -1
  41. data/app/views/api/v2/job_templates/base.json.rabl +1 -1
  42. data/app/views/api/v2/job_templates/main.json.rabl +9 -1
  43. data/app/views/api/v2/job_templates/show.json.rabl +0 -10
  44. data/app/views/api/v2/template_inputs/main.json.rabl +2 -1
  45. data/app/views/job_invocation_task_groups/_job_invocation_task_group.html.erb +1 -1
  46. data/app/views/job_invocations/_description_fields.html.erb +4 -0
  47. data/app/views/job_invocations/_form.html.erb +73 -91
  48. data/app/views/job_invocations/_host_actions_td.html.erb +2 -2
  49. data/app/views/job_invocations/_host_name_td.html.erb +7 -0
  50. data/app/views/job_invocations/_tab_hosts.html.erb +6 -6
  51. data/app/views/job_invocations/_tab_overview.html.erb +3 -3
  52. data/app/views/job_invocations/index.html.erb +6 -4
  53. data/app/views/job_invocations/refresh.js.erb +1 -0
  54. data/app/views/job_invocations/show.html.erb +1 -1
  55. data/app/views/job_invocations/show.js.erb +6 -3
  56. data/app/views/job_templates/_custom_tabs.html.erb +24 -14
  57. data/app/views/job_templates/index.html.erb +3 -1
  58. data/app/views/template_inputs/_foreign_input_set_form.html.erb +12 -0
  59. data/app/views/template_inputs/_form.html.erb +11 -12
  60. data/app/views/template_invocations/show.html.erb +2 -2
  61. data/app/views/templates/package_action.erb +2 -2
  62. data/app/views/templates/puppet_run_once.erb +3 -3
  63. data/app/views/templates/run_command.erb +3 -3
  64. data/app/views/templates/service_action.erb +2 -2
  65. data/app/views/unattended/snippets/_remote_execution_ssh_keys.erb +1 -1
  66. data/config/routes.rb +5 -3
  67. data/db/migrate/20150616080015_create_template_input.rb +1 -1
  68. data/db/migrate/20150708133241_add_targeting.rb +7 -7
  69. data/db/migrate/20150708133242_add_invocation.rb +2 -2
  70. data/db/migrate/20150708133305_add_template_invocation.rb +6 -6
  71. data/db/migrate/20151215114631_add_host_id_to_template_invocation.rb +3 -3
  72. data/db/migrate/20151217092555_migrate_to_task_groups.rb +1 -1
  73. data/db/migrate/20160108134600_create_template_input_sets.rb +16 -0
  74. data/db/migrate/20160108141144_make_job_name_default_to_something.rb +9 -0
  75. data/db/migrate/20160111113032_upcase_ssh_feature.rb +19 -0
  76. data/db/migrate/20160113161916_add_run_host_job_task_id_to_template_invocation.rb +6 -0
  77. data/db/migrate/20160113162007_expand_all_template_invocations.rb +45 -0
  78. data/db/migrate/20160114120200_rename_job_categories.rb +20 -0
  79. data/db/migrate/20160114125628_rename_job_name_to_job_category.rb +19 -0
  80. data/db/seeds.d/60-ssh_proxy_feature.rb +1 -1
  81. data/db/seeds.d/80-provision_templates.rb +2 -2
  82. data/db/seeds.d/90-bookmarks.rb +19 -0
  83. data/doc/plugins/graphviz.rb +5 -5
  84. data/doc/plugins/plantuml.rb +6 -6
  85. data/doc/plugins/tags.rb +4 -4
  86. data/foreman_remote_execution.gemspec +3 -4
  87. data/lib/foreman_remote_execution/engine.rb +12 -9
  88. data/lib/foreman_remote_execution/version.rb +1 -1
  89. data/test/factories/foreman_remote_execution_factories.rb +11 -9
  90. data/test/functional/api/v2/foreign_input_sets_controller_test.rb +63 -0
  91. data/test/functional/api/v2/job_invocations_controller_test.rb +45 -13
  92. data/test/functional/api/v2/job_templates_controller_test.rb +6 -6
  93. data/test/functional/api/v2/template_inputs_controller_test.rb +3 -3
  94. data/test/unit/actions/run_hosts_job_test.rb +3 -4
  95. data/test/unit/actions/run_proxy_command_test.rb +7 -7
  96. data/test/unit/concerns/host_extensions_test.rb +1 -1
  97. data/test/unit/execution_task_status_mapper_test.rb +93 -0
  98. data/test/unit/input_template_renderer_test.rb +182 -9
  99. data/test/unit/job_invocation_composer_test.rb +144 -168
  100. data/test/unit/job_invocation_test.rb +67 -15
  101. data/test/unit/job_template_effective_user_test.rb +2 -2
  102. data/test/unit/job_template_test.rb +36 -12
  103. data/test/unit/remote_execution_provider_test.rb +6 -6
  104. data/test/unit/targeting_test.rb +2 -2
  105. metadata +27 -21
  106. data/app/models/concerns/foreman_remote_execution/template_relations.rb +0 -10
  107. data/app/views/job_invocations/_host_provider_td.html.erb +0 -3
  108. data/app/views/job_templates/auto_complete_job_name.json.erb +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3de54e0a9f145a63c004e5e569305d4207167111
4
- data.tar.gz: 9cea79ef9465ceb6b2164f3eb9b072c45753a0bb
3
+ metadata.gz: fdc605ffe45ecda6a6b4689598d5a445884f023a
4
+ data.tar.gz: 44a2f051b425edf500e4aca917c835484a5b7af3
5
5
  SHA512:
6
- metadata.gz: e0dde3c38bf68c68c6cadeb4b5c78d1d916be96b92e0dcd313bb1fb0f2113c8003b2e652c95c3dba8138afb680bb5c40fa631131aa5ff4bb589373f209107993
7
- data.tar.gz: 9057f5eaad349a39352a6ecaeeee828978695e58c8f9b20fe10e4395c1ea60066b469bd776f7470cf69dee44a463407a1abca512c584108760143cc5f35afbbc
6
+ metadata.gz: 8d8cda76fef2487397ca8a59433b5ef526c04b5a44ebe6604cf2c9b12b21f05d28a32d2d313cf72eb13cca83b2f05809839099847f68b0a6f750dd85168312e1
7
+ data.tar.gz: f142c1067294ff125544b699528d24f4036ebc2d748d817ccf6b43428a22e0f8880fca4dea57d27d04b7651a9088480c69df559c755b81453d0490fedc31a034
data/.rubocop.yml CHANGED
@@ -45,3 +45,6 @@ Style/ClassAndModuleChildren:
45
45
 
46
46
  Style/EachWithObject:
47
47
  Enabled: false
48
+
49
+ Metrics/ParameterLists:
50
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -195,12 +195,6 @@ Style/SpaceInsideBrackets:
195
195
  Style/SpaceInsideHashLiteralBraces:
196
196
  Enabled: false
197
197
 
198
- # Offense count: 19
199
- # Cop supports --auto-correct.
200
- # Configuration parameters: EnforcedStyle, SupportedStyles.
201
- Style/StringLiterals:
202
- Enabled: false
203
-
204
198
  # Offense count: 1
205
199
  # Cop supports --auto-correct.
206
200
  # Configuration parameters: IgnoredMethods.
@@ -7,3 +7,8 @@ function update_visibility_after_input_type_change(select){
7
7
  fieldset.find('div.custom_input_type_fields').hide();
8
8
  fieldset.find('div.' + select.val() + '_input_type').show();
9
9
  }
10
+
11
+ function update_foreign_input_set_include(include_all_checkbox) {
12
+ fieldset = $(include_all_checkbox.closest('fieldset'));
13
+ fieldset.find('input.foreign_input_set_include').prop('disabled', include_all_checkbox.checked);
14
+ }
@@ -1,6 +1,6 @@
1
1
  $(function() { job_invocation_form_binds() });
2
2
 
3
- function refresh_execution_form() {
3
+ function refresh_execution_form(perform_description_reset) {
4
4
  var form = $('form#job_invocation_form');
5
5
  var data = form.serializeArray();
6
6
 
@@ -15,6 +15,11 @@ function refresh_execution_form() {
15
15
  password_caps_lock_hint();
16
16
  form.find('a[rel="popover-modal"]').popover({html: true});
17
17
  form.find('select').select2({allowClear: true});
18
+ if(perform_description_reset == true) {
19
+ var fieldset = $('fieldset#job_template_' + $('select.job_template_selector').val());
20
+ reset_description(fieldset);
21
+ }
22
+ template_change($('select.job_template_selector'));
18
23
  job_invocation_form_binds();
19
24
  });
20
25
  }
@@ -52,13 +57,15 @@ function close_preview_hosts_modal() {
52
57
  }
53
58
 
54
59
  function job_invocation_form_binds() {
55
- $('input.job_template_selector').on('click', function () {
56
- parent_fieldset = $(this).closest('fieldset');
57
- $(parent_fieldset).find('fieldset.job_template_form').hide();
60
+ $('select.job_template_selector').on('click', function () {
61
+ provider_fieldset = $('#provider_' + $(this).data('providerType'));
62
+ $(provider_fieldset).find('fieldset.job_template_form').hide();
58
63
  $('#job_template_' + $(this).val()).show();
59
64
  });
60
65
 
61
- $('select#job_invocation_job_name').on('change', refresh_execution_form);
66
+ $('select#job_invocation_job_category').on('change', function() {
67
+ refresh_execution_form(true);
68
+ });
62
69
 
63
70
  $('button#refresh_execution_form').on('click', refresh_execution_form);
64
71
 
@@ -85,8 +92,8 @@ function delayed_refresh(url, data){
85
92
  function job_invocation_refresh_data(){
86
93
  return {
87
94
  hosts_needs_refresh: $("div#hosts").data('refresh_required'),
95
+ host_ids_needing_name_update: fetch_ids_of_hosts('name'),
88
96
  host_ids_needing_status_update: fetch_ids_of_hosts('status'),
89
- host_ids_needing_provider_update: fetch_ids_of_hosts('provider'),
90
97
  host_ids_needing_actions_update: fetch_ids_of_hosts('actions')
91
98
  }
92
99
  }
@@ -98,26 +105,27 @@ function fetch_ids_of_hosts(attribute){
98
105
  function regenerate_description(thing) {
99
106
  var fieldset = $(thing).closest('fieldset');
100
107
  var dict = load_keys(fieldset);
101
- var format = fieldset.find('#description_format').val();
102
- fieldset.find('#description').val(String.format(format, dict));
108
+ var format = fieldset.find('.description_format').val();
109
+ fieldset.find('.description').val(String.format(format, dict));
103
110
  }
104
111
 
105
112
  function load_keys(parent) {
106
113
  var dict = {};
107
- var pattern = $(parent).find("#description_format").val();
114
+ var pattern = $(parent).find(".description_format").val();
108
115
  var re = new RegExp("%\\{([^\\}]+)\\}", "gm");
109
116
  var match = re.exec(pattern);
110
117
  while(match != null) {
111
118
  dict[match[1]] = $(parent).find("#" + match[1]).val();
112
119
  match = re.exec(pattern);
113
120
  }
114
- dict['job_name'] = $('#job_invocation_job_name').val();
121
+ dict['job_category'] = $('#job_invocation_job_category').val();
122
+ dict['template_name'] = $('.job_template_selector:visible span.select2-chosen').html();
115
123
  return dict;
116
124
  }
117
125
 
118
126
  function description_override(source) {
119
- var description_format_container = $(source).closest('fieldset').find('#description_format_container');
120
- var description_format = $(description_format_container).find('#description_format');
127
+ var description_format_container = $(source).closest('fieldset').find('.description_format_container');
128
+ var description_format = $(description_format_container).find('.description_format');
121
129
  var old_value = $(source).val();
122
130
  if($(source).is(':checked')) {
123
131
  $(description_format_container).hide();
@@ -129,6 +137,30 @@ function description_override(source) {
129
137
  regenerate_description(description_format);
130
138
  }
131
139
 
140
+ function template_change(source) {
141
+ var template_forms = $('fieldset.job_template_form');
142
+ for(i = 0; i < template_forms.length; i++) {
143
+ set_description_disable(template_forms[i], true);
144
+ }
145
+ var id = $(source).val();
146
+ var template_fieldset = $(source).closest('form').find('fieldset#job_template_' + id);
147
+ set_description_disable(template_fieldset, false);
148
+ regenerate_description(template_fieldset.find('.description'));
149
+ }
150
+
151
+ function set_description_disable(thing, value) {
152
+ $(thing).find('.description').prop('disabled', value);
153
+ $(thing).find('.description_format').prop('disabled', value);
154
+ $(thing).find('.description_format_override').prop('disabled', value);
155
+ }
156
+
157
+ function reset_description(fieldset) {
158
+ var checkbox = $(fieldset).find('.description_format_override');
159
+ $(fieldset).find('.description_format').val($(checkbox).val());
160
+ $(checkbox).prop('checked', true);
161
+ $(fieldset).find('.description_format_container').hide();
162
+ }
163
+
132
164
  String.format = function (pattern, dict) {
133
165
  if(pattern == undefined) {
134
166
  return "";
@@ -0,0 +1,80 @@
1
+ module Api
2
+ module V2
3
+ class ForeignInputSetsController < ::Api::V2::BaseController
4
+ include ::Api::Version2
5
+ include ::Foreman::Renderer
6
+
7
+ before_filter :find_required_nested_object
8
+ before_filter :find_resource, :only => %w{show update destroy}
9
+
10
+ api :GET, '/templates/:template_id/foreign_input_sets', N_('List foreign input sets')
11
+ param :template_id, :identifier, :required => true
12
+ param_group :search_and_pagination, ::Api::V2::BaseController
13
+ def index
14
+ @foreign_input_sets = nested_obj.foreign_input_sets.search_for(*search_options).paginate(paginate_options)
15
+ end
16
+
17
+ api :GET, '/templates/:template_id/foreign_input_sets/:id', N_('Show foreign input set details')
18
+ param :template_id, :identifier, :required => true
19
+ param :id, :identifier, :required => true
20
+ def show
21
+ end
22
+
23
+ def_param_group :foreign_input_set do
24
+ param :foreign_input_set, Hash, :required => true, :action_aware => true do
25
+ param :target_template_id, :identifier, :required => true, :desc => N_('Target template id')
26
+ param :include_all, :bool, :desc => N_('Include all inputs form the foreign template')
27
+ param :include, String, :desc => N_('A comma separated list of input names to be included from the foreign template.')
28
+ param :exclude, String, :desc => N_('A comma separated list of input names to be included from the foreign template.')
29
+ param :description, String, :required => false, :desc => N_('Input set description')
30
+ end
31
+ end
32
+
33
+ api :POST, '/templates/:template_id/foreign_input_sets/', N_('Create a foreign input set')
34
+ param :template_id, :identifier, :required => true
35
+ param_group :foreign_input_set, :as => :create
36
+ def create
37
+ @foreign_input_set = resource_class.new(params[:foreign_input_set].merge(:template_id => @nested_obj.id))
38
+ process_response @foreign_input_set.save
39
+ end
40
+
41
+ api :DELETE, '/templates/:template_id/foreign_input_sets/:id', N_('Delete a foreign input set')
42
+ param :template_id, :identifier, :required => true
43
+ param :id, :identifier, :required => true
44
+ def destroy
45
+ process_response @foreign_input_set.destroy
46
+ end
47
+
48
+ api :PUT, '/templates/:template_id/foreign_input_sets/:id', N_('Update a foreign input set')
49
+ param :template_id, :identifier, :required => true
50
+ param :id, :identifier, :required => true
51
+ param_group :foreign_input_set
52
+ def update
53
+ process_response @foreign_input_set.update_attributes(params[:foreign_input_set])
54
+ end
55
+
56
+ def resource_name(nested_resource = nil)
57
+ nested_resource || 'foreign_input_set'
58
+ end
59
+
60
+ def controller_permission
61
+ 'templates'
62
+ end
63
+
64
+ def action_permission
65
+ case params[:action]
66
+ when :create, :edit, :destroy
67
+ 'edit'
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def resource_class
76
+ ForeignInputSet
77
+ end
78
+ end
79
+ end
80
+ end
@@ -12,44 +12,58 @@ module Api
12
12
 
13
13
  wrap_parameters JobInvocation, :include => (JobInvocation.attribute_names + [:ssh])
14
14
 
15
- api :GET, "/job_invocations/", N_("List job invocations")
15
+ api :GET, '/job_invocations/', N_('List job invocations')
16
16
  param_group :search_and_pagination, ::Api::V2::BaseController
17
17
  def index
18
18
  @job_invocations = resource_scope_for_index
19
19
  end
20
20
 
21
- api :GET, "/job_invocations/:id", N_("Show job invocation")
21
+ api :GET, '/job_invocations/:id', N_('Show job invocation')
22
22
  param :id, :identifier, :required => true
23
23
  def show
24
24
  end
25
25
 
26
26
  def_param_group :job_invocation do
27
27
  param :job_invocation, Hash, :required => true, :action_aware => true do
28
- param :job_name, String, :required => true, :desc => N_("Job name")
29
- param :job_template_id, String, :required => false, :desc => N_("If using a specific template, the id of that template.")
30
- param :targeting_type, String, :required => true, :desc => N_("Invocation type, one of %s") % Targeting::TYPES
31
- param :inputs, Hash, :required => false, :desc => N_("Inputs to use")
32
- param :ssh, Hash, :desc => N_("Ssh provider specific options") do
28
+ param :job_category, String, :required => true, :desc => N_('Job category')
29
+ param :job_template_id, String, :required => false, :desc => N_('If using a specific template, the id of that template.')
30
+ param :targeting_type, String, :required => true, :desc => N_('Invocation type, one of %s') % Targeting::TYPES
31
+ param :inputs, Hash, :required => false, :desc => N_('Inputs to use')
32
+ param :ssh, Hash, :desc => N_('SSH provider specific options') do
33
33
  param :effective_user, String,
34
34
  :required => false,
35
- :desc => N_("What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting.")
35
+ :desc => N_('What user should be used to run the script (using sudo-like mechanisms). Defaults to a template parameter or global setting.')
36
36
  end
37
+
38
+ param :recurrence, Hash, :desc => N_('Create a recurring job') do
39
+ param :cron_line, String, :required => false, :desc => N_('How often the job should occur, in the cron format')
40
+ param :max_iteration, :number, :required => false, :desc => N_('Repeat a maximum of N times')
41
+ param :end_time, DateTime, :required => false, :desc => N_('Perform no more executions after this time')
42
+ end
43
+
44
+ param :scheduling, Hash, :desc => N_('Schedule the job to start at a later time') do
45
+ param :start_at, DateTime, :required => false, :desc => N_('Schedule the job for a future time')
46
+ param :start_before, DateTime, :required => false, :desc => N_('Indicates that the action should be cancelled if it cannot be started before this time.')
47
+ end
48
+
37
49
  param :bookmark_id, Integer, :required => false
38
50
  param :search_query, Integer, :required => false
51
+ param :description_format, String, :required => false, :desc => N_('Override the description format from the template for this invocation only')
39
52
  end
40
53
  end
41
54
 
42
- api :POST, "/job_invocations/", N_("Create a job invocation")
55
+ api :POST, '/job_invocations/', N_('Create a job invocation')
43
56
  param_group :job_invocation, :as => :create
44
57
  def create
45
58
  composer = JobInvocationComposer.from_api_params(job_invocation_params)
46
59
  composer.save!
47
- ForemanTasks.async_task(::Actions::RemoteExecution::RunHostsJob, composer.job_invocation)
48
60
  @job_invocation = composer.job_invocation
61
+ @job_invocation.generate_description! if @job_invocation.description.blank?
62
+ composer.triggering.trigger(::Actions::RemoteExecution::RunHostsJob, @job_invocation)
49
63
  process_response @job_invocation
50
64
  end
51
65
 
52
- api :GET, "/job_invocations/:id/hosts/:host_id", N_("Get output for a host")
66
+ api :GET, '/job_invocations/:id/hosts/:host_id', N_('Get output for a host')
53
67
  param :id, :identifier, :required => true
54
68
  param :host_id, :identifier, :required => true
55
69
  param :since, String, :required => false
@@ -90,13 +104,13 @@ module Api
90
104
  if job_invocation_params[:job_template_id]
91
105
  templates << JobTemplate.find(job_invocation_params[:job_template_id])
92
106
  else
93
- templates = JobTemplate.where(:job_name => job_invocation_params[:job_name])
107
+ templates = JobTemplate.where(:job_category => job_invocation_params[:job_category])
94
108
  if templates.pluck(:provider_type).uniq.length != templates.length
95
- raise Foreman::Exception, _("Duplicate remote execution providers found for specified Job, please specify a single job_template_id.")
109
+ raise Foreman::Exception, _('Duplicate remote execution providers found for specified Job, please specify a single job_template_id.')
96
110
  end
97
111
  end
98
112
 
99
- raise Foreman::Exception, _("No templates associated with specified Job Name") if templates.empty?
113
+ raise Foreman::Exception, _('No templates associated with specified Job Name') if templates.empty?
100
114
  end
101
115
 
102
116
  def job_invocation_params
@@ -13,62 +13,66 @@ module Api
13
13
 
14
14
  wrap_parameters JobTemplate, :include => (JobTemplate.attribute_names + [:ssh])
15
15
 
16
- api :GET, "/job_templates/", N_("List job templates")
17
- api :GET, "/locations/:location_id/job_templates/", N_("List job templates per location")
18
- api :GET, "/organizations/:organization_id/job_templates/", N_("List job templates per organization")
16
+ api :GET, '/job_templates/', N_('List job templates')
17
+ api :GET, '/locations/:location_id/job_templates/', N_('List job templates per location')
18
+ api :GET, '/organizations/:organization_id/job_templates/', N_('List job templates per organization')
19
19
  param_group :taxonomy_scope, ::Api::V2::BaseController
20
20
  param_group :search_and_pagination, ::Api::V2::BaseController
21
21
  def index
22
22
  @job_templates = resource_scope_for_index
23
23
  end
24
24
 
25
- api :GET, "/job_templates/:id", N_("Show job template details")
25
+ api :GET, '/job_templates/:id', N_('Show job template details')
26
26
  param :id, :identifier, :required => true
27
27
  def show
28
28
  end
29
29
 
30
30
  def_param_group :job_template do
31
31
  param :job_template, Hash, :required => true, :action_aware => true do
32
- param :name, String, :required => true, :desc => N_("Template name")
33
- param :job_name, String, :required => true, :desc => N_("Job name")
32
+ param :name, String, :required => true, :desc => N_('Template name')
33
+ param :job_category, String, :required => true, :desc => N_('Job category')
34
+ param :description_format, String, :required => false, :desc => N_('This template is used to generate the description. ' +
35
+ 'Input values can be used using the syntax %{package}. ' +
36
+ 'You may also include the job category and template ' +
37
+ 'name using %{job_category} and %{template_name}.')
34
38
  param :template, String, :required => true
35
- param :provider_type, RemoteExecutionProvider.provider_names, :required => true, :desc => N_("Provider type")
39
+ param :provider_type, RemoteExecutionProvider.provider_names, :required => true, :desc => N_('Provider type')
36
40
  param :snippet, :bool, :allow_nil => true
37
41
  param :audit_comment, String, :allow_nil => true
38
- param :locked, :bool, :desc => N_("Whether or not the template is locked for editing")
39
- param :ssh, Hash, :desc => N_("Ssh provider specific options") do
40
- param :effective_user, Hash, :desc => N_("Effective user options") do
41
- param :value, String, :desc => N_("What user should be used to run the script (using sudo-like mechanisms)"), :allowed_nil => true
42
- param :overridable, :bool, :desc => N_("Whether it should be allowed to override the effective user from the invocation form.")
43
- param :current_user, :bool, :desc => N_("Whether the current user login should be used as the effective user")
42
+ param :locked, :bool, :desc => N_('Whether or not the template is locked for editing')
43
+ param :ssh, Hash, :desc => N_('SSH provider specific options') do
44
+ param :effective_user, Hash, :desc => N_('Effective user options') do
45
+ param :value, String, :desc => N_('What user should be used to run the script (using sudo-like mechanisms)'), :allowed_nil => true
46
+ param :overridable, :bool, :desc => N_('Whether it should be allowed to override the effective user from the invocation form.')
47
+ param :current_user, :bool, :desc => N_('Whether the current user login should be used as the effective user')
44
48
  end
45
49
  end
46
50
  param_group :taxonomies, ::Api::V2::BaseController
47
51
  end
48
52
  end
49
53
 
50
- api :POST, "/job_templates/", N_("Create a job template")
54
+ api :POST, '/job_templates/', N_('Create a job template')
51
55
  param_group :job_template, :as => :create
52
56
  def create
53
57
  @job_template = JobTemplate.new(job_template_params)
54
58
  process_response @job_template.save
55
59
  end
56
60
 
57
- api :PUT, "/job_templates/:id", N_("Update a job template")
61
+ api :PUT, '/job_templates/:id', N_('Update a job template')
58
62
  param :id, :identifier, :required => true
59
63
  param_group :job_template
60
64
  def update
61
65
  process_response @job_template.update_attributes(job_template_params)
62
66
  end
63
67
 
64
- api :GET, "/job_templates/revision"
65
- param :version, String, :desc => N_("Template version")
68
+ api :GET, '/job_templates/revision'
69
+ param :version, String, :desc => N_('Template version')
66
70
  def revision
67
71
  audit = Audit.authorized(:view_audit_logs).find(params[:version])
68
72
  render :json => audit.revision.template
69
73
  end
70
74
 
71
- api :DELETE, "/job_templates/:id", N_("Delete a job template")
75
+ api :DELETE, '/job_templates/:id', N_('Delete a job template')
72
76
  param :id, :identifier, :required => true
73
77
  def destroy
74
78
  process_response @job_template.destroy
@@ -76,11 +80,11 @@ module Api
76
80
 
77
81
  def_param_group :job_template_clone do
78
82
  param :job_template, Hash, :required => true, :action_aware => true do
79
- param :name, String, :required => true, :desc => N_("Template name")
83
+ param :name, String, :required => true, :desc => N_('Template name')
80
84
  end
81
85
  end
82
86
 
83
- api :POST, "/job_templates/:id/clone", N_("Clone a provision template")
87
+ api :POST, '/job_templates/:id/clone', N_('Clone a provision template')
84
88
  param :id, :identifier, :required => true
85
89
  param_group :job_template_clone, :as => :create
86
90
  def clone
@@ -5,17 +5,17 @@ module Api
5
5
  include ::Foreman::Renderer
6
6
 
7
7
  before_filter :find_required_nested_object
8
- before_filter :find_resource, :only => %w{show update destroy clone}
8
+ before_filter :find_resource, :only => %w{show update destroy}
9
9
  before_filter :normalize_options, :only => %w{create update}
10
10
 
11
- api :GET, "/templates/:template_id/template_inputs", N_("List template inputs")
11
+ api :GET, '/templates/:template_id/template_inputs', N_('List template inputs')
12
12
  param :template_id, :identifier, :required => true
13
13
  param_group :search_and_pagination, ::Api::V2::BaseController
14
14
  def index
15
15
  @template_inputs = nested_obj.template_inputs.search_for(*search_options).paginate(paginate_options)
16
16
  end
17
17
 
18
- api :GET, "/templates/:template_id/template_inputs/:id", N_("Show template input details")
18
+ api :GET, '/templates/:template_id/template_inputs/:id', N_('Show template input details')
19
19
  param :template_id, :identifier, :required => true
20
20
  param :id, :identifier, :required => true
21
21
  def show
@@ -24,30 +24,33 @@ module Api
24
24
  def_param_group :template_input do
25
25
  param :template_input, Hash, :required => true, :action_aware => true do
26
26
  param :name, String, :required => true, :desc => N_('Input name')
27
+ param :description, String, :required => false, :desc => N_('Input description')
28
+ param :required, :bool, :allow_nil => true, :desc => N_('Input is required')
27
29
  param :input_type, TemplateInput::TYPES.keys.map(&:to_s), :required => true, :desc => N_('Input type')
28
30
  param :fact_name, String, :required => false, :desc => N_('Fact name, used when input type is fact')
29
31
  param :variable_name, String, :required => false, :desc => N_('Variable name, used when input type is variable')
32
+ param :puppet_parameter_class, String, :required => false, :desc => N_('Puppet class name, used when input type is puppet_parameter')
30
33
  param :puppet_parameter_name, String, :required => false, :desc => N_('Puppet parameter name, used when input type is puppet_parameter')
31
34
  param :options, Array, :required => false, :desc => N_('Selectable values for user inputs')
32
35
  end
33
36
  end
34
37
 
35
- api :POST, "/templates/:template_id/template_inputs/", N_("Create a template input")
38
+ api :POST, '/templates/:template_id/template_inputs/', N_('Create a template input')
36
39
  param :template_id, :identifier, :required => true
37
40
  param_group :template_input, :as => :create
38
41
  def create
39
- @template_input = TemplateInput.new(params[:template_input].merge(:template_id => @nested_obj.id))
42
+ @template_input = resource_class.new(params[:template_input].merge(:template_id => @nested_obj.id))
40
43
  process_response @template_input.save
41
44
  end
42
45
 
43
- api :DELETE, "/templates/:template_id/template_inputs/:id", N_("Delete a template input")
46
+ api :DELETE, '/templates/:template_id/template_inputs/:id', N_('Delete a template input')
44
47
  param :template_id, :identifier, :required => true
45
48
  param :id, :identifier, :required => true
46
49
  def destroy
47
50
  process_response @template_input.destroy
48
51
  end
49
52
 
50
- api :PUT, "/templates/:template_id/template_inputs/:id", N_("Update a template input")
53
+ api :PUT, '/templates/:template_id/template_inputs/:id', N_('Update a template input')
51
54
  param :template_id, :identifier, :required => true
52
55
  param :id, :identifier, :required => true
53
56
  param_group :template_input