foreman_remote_execution 0.1.2 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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