foreman_acd 0.2.1 → 0.3.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +122 -0
  3. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +54 -0
  4. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +54 -0
  5. data/app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb +0 -0
  6. data/app/controllers/foreman_acd/app_definitions_controller.rb +7 -4
  7. data/app/controllers/foreman_acd/app_instances_controller.rb +33 -126
  8. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +23 -0
  9. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  10. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  11. data/app/controllers/ui_acd_controller.rb +11 -3
  12. data/app/models/foreman_acd/ansible_playbook.rb +50 -0
  13. data/app/models/foreman_acd/app_definition.rb +2 -0
  14. data/app/models/foreman_acd/app_instance.rb +7 -0
  15. data/app/services/foreman_acd/app_configurator.rb +70 -0
  16. data/app/services/foreman_acd/app_deployer.rb +143 -0
  17. data/app/services/foreman_acd/inventory_creator.rb +67 -0
  18. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +21 -0
  19. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +3 -0
  20. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  21. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  22. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +3 -0
  23. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +3 -0
  24. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +3 -0
  25. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +3 -0
  26. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +3 -0
  27. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +3 -0
  28. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -0
  29. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +3 -0
  30. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +3 -0
  31. data/app/views/foreman_acd/app_definitions/_form.html.erb +24 -10
  32. data/app/views/foreman_acd/app_definitions/edit.html.erb +5 -0
  33. data/app/views/foreman_acd/app_instances/_form.html.erb +7 -5
  34. data/app/views/foreman_acd/app_instances/index.html.erb +5 -1
  35. data/app/views/templates/job/run_acd_ansible_playbook.erb +49 -0
  36. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  37. data/app/views/ui_acd/app.json.rabl +6 -2
  38. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  39. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  40. data/config/routes.rb +24 -1
  41. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  42. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  43. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +5 -0
  44. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +5 -0
  45. data/db/seeds.d/75-job_templates.rb +8 -0
  46. data/lib/foreman_acd/engine.rb +3 -0
  47. data/lib/foreman_acd/plugin.rb +53 -2
  48. data/lib/foreman_acd/version.rb +1 -1
  49. data/package.json +1 -1
  50. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +137 -22
  51. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +95 -11
  52. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +7 -2
  53. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  54. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +117 -21
  55. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +2 -0
  56. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  57. data/webpack/components/ApplicationDefinition/index.js +4 -0
  58. data/webpack/components/ApplicationInstance/ApplicationInstance.js +92 -22
  59. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +37 -8
  60. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +4 -2
  61. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +98 -26
  62. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +2 -1
  63. data/webpack/components/ApplicationInstance/index.js +2 -0
  64. data/webpack/components/ParameterSelection/ParameterSelection.js +46 -37
  65. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +49 -52
  66. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +5 -3
  67. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +0 -32
  68. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +32 -16
  69. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +2 -2
  70. data/webpack/components/ParameterSelection/index.js +4 -4
  71. data/webpack/components/common/DeleteTableEntry.js +1 -1
  72. data/webpack/reducer.js +14 -11
  73. metadata +48 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef0b36ad161877bede4fe9a9df532a8201fc31710b1f42ab988152aeba863cac
4
- data.tar.gz: a629384ff81f18c21883ea4a09a76828988bff02e6a709a7f2151e77fff46836
3
+ metadata.gz: 63b0fc4a685be137bfd8d72d166d0c157081dc4c2ad34cbde4ac7e75faed4e1a
4
+ data.tar.gz: 9484df12c6738faa15f1b6d76721992b74a5ae0a795bbe6fc1f20cb08d3e7edd
5
5
  SHA512:
6
- metadata.gz: 8c8843594e0cbad7c6b85398c8b4d2c8fe18703ef7dc5c2ebd4fd46ccd0690a3cf30588e13dcef66e9d568fa4c5ca97fd272ebb5f5107e3f2ad1258f9fb9d35f
7
- data.tar.gz: 99181b0218e89485fffedfdd1374b095c1830614718332246f72238af50adb65610e03fdaa0a035f6cd68208d8f72679b141eac2b558dc1824abb30b21120b56
6
+ metadata.gz: 18caaab55b04561db5addf6d8376d37a4d7b043ccf7bba5cc98bb3d4fbc4b163b1a72416a5cffae556fa08626377dfa94608a0946d7009fd34a89989e96e9679
7
+ data.tar.gz: 7f00242c823cf86a6a315885009d19ed05b8215fbfd3b2d973a819aad716dfe576fdc719b8d3b1ea3f5c869fed1eb4b3647aa264aedcca8c6a0dc24fc237085f
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ # Ansible Playbook Controller
5
+ class AnsiblePlaybooksController < ::ForemanAcd::ApplicationController
6
+ include Foreman::Controller::AutoCompleteSearch
7
+ include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
8
+
9
+ before_action :find_resource, :only => [:edit, :update, :destroy, :import_vars]
10
+
11
+ def index
12
+ @ansible_playbooks = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
+ end
14
+
15
+ def new
16
+ @ansible_playbook = AnsiblePlaybook.new
17
+ end
18
+
19
+ def create
20
+ @ansible_playbook = AnsiblePlaybook.new(ansible_playbook_params)
21
+ if @ansible_playbook.save
22
+ process_success
23
+ else
24
+ process_error
25
+ end
26
+ end
27
+
28
+ def edit
29
+ end
30
+
31
+ def update
32
+ if @ansible_playbook.update(ansible_playbook_params)
33
+ process_success
34
+ else
35
+ process_error
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ if @ansible_playbook.destroy
41
+ process_success
42
+ else
43
+ process_error
44
+ end
45
+ end
46
+
47
+ def action_permission
48
+ case params[:action]
49
+ when 'import_vars'
50
+ :import_vars
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ # We need to move these to a smart_proxy_acd
57
+ def extract_variables(playbook_path)
58
+ errors = []
59
+ vars = {}
60
+
61
+ unless File.directory?(playbook_path) || File.directory?("#{playbook_path}/group_vars")
62
+ errors << "Playbook path '#{playbook_path}' or '#{playbook_path}/group_vars' doesn't exist"
63
+ return vars, errors
64
+ end
65
+
66
+ everything_empty = true
67
+
68
+ vars_files = Dir.glob("#{playbook_path}/group_vars/**/*")
69
+ vars_files.each do |vars_file|
70
+ loaded_yaml = {}
71
+ next if File.directory?(vars_file)
72
+
73
+ begin
74
+ loaded_yaml = YAML.load_file(vars_file)
75
+ rescue Psych::SyntaxError
76
+ err = "#{vars_file} is not YAML file"
77
+ logger.error(err)
78
+ errors << err
79
+ end
80
+ unless loaded_yaml.is_a? Hash
81
+ err = "Could not parse YAML file #{vars_file}"
82
+ logger.error(err)
83
+ errors << err
84
+ end
85
+ everything_empty = false unless loaded_yaml.empty?
86
+
87
+ # We need to support: group_vars/group_file and group_vars/group_dir/yaml_files
88
+ dir_and_file = File.split(vars_file)
89
+ basename = File.basename(dir_and_file[0], '.*')
90
+ if basename == 'group_vars'
91
+ group_name = dir_and_file[1]
92
+ else
93
+ group_name = basename
94
+ end
95
+
96
+ logger.debug("Add ansible vars from file #{vars_file} to group #{group_name}")
97
+
98
+ if vars.has_key?(group_name)
99
+ vars[group_name].merge!(loaded_yaml)
100
+ else
101
+ vars[group_name] = loaded_yaml
102
+ end
103
+ end
104
+
105
+ errors << "No ansible group variable in #{playbook_path} defined." if everything_empty
106
+
107
+ return vars, errors
108
+ end
109
+
110
+ def import_vars
111
+ logger.debug("Load ansible group vars for #{@ansible_playbook} from #{@ansible_playbook.path}")
112
+ vars, errors = extract_variables(@ansible_playbook.path)
113
+ @ansible_playbook.vars = vars.to_json
114
+ @ansible_playbook.save
115
+ if errors.empty?
116
+ process_success :success_msg => _("Successfully loaded ansible group variables from %s") % @ansible_playbook.name, :redirect => ansible_playbooks_path
117
+ else
118
+ process_error :error_msg => _(errors.join(' ')), :redirect => ansible_playbooks_path
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # API controller for Ansible Playbooks
7
+ class AnsiblePlaybooksController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::ForemanAcd::Concerns::AnsiblePlaybookParameters
9
+
10
+ before_action :find_resource, :except => [:index, :create]
11
+
12
+ api :GET, '/ansible_playbooks/:id', N_('Show ansible playbook')
13
+ param :id, :identifier, :required => true
14
+ def show; end
15
+
16
+ api :GET, '/ansible_playbooks', N_('List ansible playbooks')
17
+ param_group :search_and_pagination, ::Api::V2::BaseController
18
+ add_scoped_search_description_for(AnsiblePlaybook)
19
+ def index
20
+ @ansible_playbooks = resource_scope_for_index
21
+ end
22
+
23
+ def_param_group :ansible_playbook do
24
+ param :ansible_playbook, Hash, :required => true, :action_aware => true do
25
+ param :name, String, :required => true
26
+ param :description, String, :required => true
27
+ param :services, String, :required => true
28
+ end
29
+ end
30
+
31
+ api :POST, '/ansible_playbooks', N_('Create a ansible playbook')
32
+ param_group :ansible_playbook, :as => :create
33
+ def create
34
+ @ansible_playbook = AnsiblePlaybook.new(ansible_playbook_params)
35
+ process_response @ansible_playbook.save
36
+ end
37
+
38
+ api :DELETE, '/ansible_playbooks/:id', N_('Deletes ansible playbook')
39
+ param :id, :identifier, :required => true
40
+ def destroy
41
+ process_response @ansible_playbook.destroy
42
+ end
43
+
44
+ def controller_permission
45
+ 'ansible_playbooks'
46
+ end
47
+
48
+ def resource_class
49
+ ForemanAcd::AnsiblePlaybook
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ForemanAcd
4
+ module Api
5
+ module V2
6
+ # API controller for App Instances
7
+ class AppInstancesController < ::ForemanAcd::Api::V2::BaseController
8
+ include ::ForemanAcd::Concerns::AppInstanceParameters
9
+
10
+ before_action :find_resource, :except => [:index, :create]
11
+
12
+ api :GET, '/app_instances/:id', N_('Show application instance')
13
+ param :id, :identifier, :required => true
14
+ def show; end
15
+
16
+ api :GET, '/app_instances', N_('List application instances')
17
+ param_group :search_and_pagination, ::Api::V2::BaseController
18
+ add_scoped_search_description_for(AppInstance)
19
+ def index
20
+ @app_instances = resource_scope_for_index
21
+ end
22
+
23
+ def_param_group :app_instance do
24
+ param :app_instance, Hash, :required => true, :action_aware => true do
25
+ param :name, String, :required => true
26
+ param :description, String, :required => true
27
+ param :services, String, :required => true
28
+ end
29
+ end
30
+
31
+ api :POST, '/app_instances', N_('Create a application instance')
32
+ param_group :app_instance, :as => :create
33
+ def create
34
+ @app_instance = AppInstance.new(app_instance_params)
35
+ process_response @app_instance.save
36
+ end
37
+
38
+ api :DELETE, '/app_instances/:id', N_('Deletes application instance')
39
+ param :id, :identifier, :required => true
40
+ def destroy
41
+ process_response @app_instance.destroy
42
+ end
43
+
44
+ def controller_permission
45
+ 'app_instances'
46
+ end
47
+
48
+ def resource_class
49
+ ForemanAcd::AppInstance
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -7,18 +7,23 @@ module ForemanAcd
7
7
  include ::ForemanAcd::Concerns::AppDefinitionParameters
8
8
 
9
9
  before_action :find_resource, :only => [:edit, :update, :destroy, :export]
10
+ before_action :read_hostgroups, :only => [:edit, :new, :import]
11
+ before_action :read_ansible_playbooks, :only => [:edit, :new]
10
12
  before_action :handle_file_upload, :only => [:create]
11
13
 
12
14
  def index
13
15
  @app_definitions = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
14
16
  end
15
17
 
18
+ def read_ansible_playbooks
19
+ @ansible_playbooks = AnsiblePlaybook.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
20
+ end
21
+
16
22
  def read_hostgroups
17
23
  @hostgroups = Hostgroup.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
18
24
  end
19
25
 
20
26
  def new
21
- read_hostgroups
22
27
  @app_definition = AppDefinition.new
23
28
  end
24
29
 
@@ -32,11 +37,10 @@ module ForemanAcd
32
37
  end
33
38
 
34
39
  def edit
35
- read_hostgroups
36
40
  end
37
41
 
38
42
  def update
39
- if @app_definition.update(app_definition_params)
43
+ if @app_definition.update_attributes(app_definition_params)
40
44
  process_success
41
45
  else
42
46
  process_error
@@ -61,7 +65,6 @@ module ForemanAcd
61
65
  end
62
66
 
63
67
  def import
64
- read_hostgroups
65
68
  @app_definition = AppDefinition.new
66
69
  end
67
70
 
@@ -6,19 +6,19 @@ module ForemanAcd
6
6
  include Foreman::Controller::AutoCompleteSearch
7
7
  include ::ForemanAcd::Concerns::AppInstanceParameters
8
8
 
9
- before_action :find_resource, :only => [:edit, :update, :destroy, :deploy, :report]
9
+ before_action :find_resource, :only => [:edit, :update, :destroy, :deploy, :report, :configure]
10
+ before_action :read_applications, :only => [:new, :edit]
10
11
 
11
12
  def index
12
13
  @app_instances = resource_base.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page])
13
14
  end
14
15
 
15
16
  def read_applications
16
- @applications = ForemanAcd::AppDefinition.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
17
+ @applications = AppDefinition.all.map { |elem| { elem.id => elem.name } }.reduce({}) { |h, v| h.merge v }
17
18
  end
18
19
 
19
20
  def new
20
21
  @app_instance = AppInstance.new
21
- read_applications
22
22
  end
23
23
 
24
24
  def create
@@ -31,7 +31,6 @@ module ForemanAcd
31
31
  end
32
32
 
33
33
  def edit
34
- read_applications
35
34
  end
36
35
 
37
36
  def update
@@ -56,63 +55,21 @@ module ForemanAcd
56
55
  :deploy
57
56
  when 'report'
58
57
  :report
58
+ when 'configure'
59
+ :configure
59
60
  else
60
61
  super
61
62
  end
62
63
  end
63
64
 
64
65
  def deploy
65
- services = JSON.parse(@app_instance.app_definition.services)
66
- @deploy_hosts = []
67
-
68
- app_hosts = JSON.parse(@app_instance.hosts)
69
-
70
- app_hosts.each do |host_data|
71
- begin
72
- service_data = services.select { |k| k['id'] == host_data['service'].to_i }.first
73
- host_params = set_host_params(host_data, service_data)
74
-
75
- host = nil
76
- if host_data.has_key?('foreman_host_id')
77
- logger.debug("Try to find host with id #{host_data['foreman_host_id']}")
78
- begin
79
- host = Host.find(host_data['foreman_host_id'])
80
- rescue ActiveRecord::RecordNotFound
81
- logger.info("Host with id #{host_data['foreman_host_id']} couldn\'t be found, create a new one!")
82
- host = nil
83
- end
84
- end
85
-
86
- if host.nil?
87
- logger.info("Host creation parameters for #{host_data['hostname']}:\n#{params}\n")
88
- params = host_attributes(host_params)
89
- host = Host.new(params)
90
- else
91
- logger.info("Update parameters and re-deploy host #{host_data['hostname']}")
92
- host.attributes = host_attributes(host_params, host)
93
- host.setBuild
94
- host.power.reset
95
- end
96
-
97
- # REMOVE ME (but very nice for testing)
98
- #host.mac = "00:11:22:33:44:55"
99
-
100
- apply_compute_profile(host)
101
- host.suggest_default_pxe_loader
102
- host.save
103
-
104
- # save the foreman host id
105
- host_data['foreman_host_id'] = host.id
106
-
107
- @deploy_hosts.push({ id: host.id, name: host_data['hostname'], hostname: host.hostname, hostUrl: host_path(h), progress_report_id: host.progress_report_id})
108
- rescue StandardError => e
109
- logger.error("Failed to initiate host creation: #{e.backtrace.join($INPUT_RECORD_SEPARATOR)}")
110
- end
111
- end
66
+ app_deployer = ForemanAcd::AppDeployer.new(@app_instance)
112
67
 
113
68
  # save any change to the app_hosts json
114
- @app_instance.hosts = app_hosts.to_json
69
+ @app_instance.hosts = app_deployer.deploy.to_json
115
70
  @app_instance.save
71
+
72
+ @deploy_hosts = app_deployer.deploy_hosts
116
73
  end
117
74
 
118
75
  def report
@@ -126,82 +83,32 @@ module ForemanAcd
126
83
  logger.debug("deploy report hosts are: #{@report_hosts.inspect}")
127
84
  end
128
85
 
129
- private
130
-
131
- # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
132
- def apply_compute_profile(host)
133
- host.apply_compute_profile(InterfaceMerge.new(:merge_compute_attributes => true))
134
- host.apply_compute_profile(ComputeAttributeMerge.new)
135
- end
136
-
137
- # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
138
- def host_attributes(params, host = nil)
139
- return {} if params.nil?
140
-
141
- params = params.deep_clone
142
- if params[:interfaces_attributes]
143
- # handle both hash and array styles of nested attributes
144
- params[:interfaces_attributes] = params[:interfaces_attributes].values if params[:interfaces_attributes].is_a?(Hash) || params[:interfaces_attributes].is_a?(ActionController::Parameters)
145
- # map interface types
146
- params[:interfaces_attributes] = params[:interfaces_attributes].map do |nic_attr|
147
- interface_attributes(nic_attr, :allow_nil_type => host.nil?)
148
- end
149
- end
150
- params = host.apply_inherited_attributes(params) if host
151
- params
152
- end
153
-
154
- # Copied from foreman/app/controllers/api/v2/hosts_controller.rb
155
- def interface_attributes(params, allow_nil_type: false)
156
- params[:type] = InterfaceTypeMapper.map(params[:type]) if params.key?(:type) || allow_nil_type
157
- params
158
- end
159
-
160
- def hardcoded_params
161
- result = {}
162
- result['managed'] = true
163
- result['enabled'] = true
164
- result['build'] = true
165
- result['compute_attributes'] = { 'start' => '1' }
166
- result['host_parameters_attributes'] = []
167
- result
168
- end
169
-
170
- def set_host_params(host_data, service_data)
171
- result = hardcoded_params
172
- result['name'] = host_data['hostname']
173
- result['hostgroup_id'] = service_data['hostgroup']
174
-
175
- host_data['parameters'].each do |param|
176
- case param['type']
177
-
178
- when 'computeprofile'
179
- result['compute_profile_id'] = param['value']
180
-
181
- when 'domain'
182
- result['domain_id'] = param['value']
183
-
184
- when 'hostparam'
185
- result['host_parameters_attributes'].push(:name => param['name'], :value => param['value'])
186
-
187
- when 'ip'
188
- result['ip'] = param['value']
189
-
190
- when 'lifecycleenv'
191
- result['content_facet_attributes'] = { 'lifecycle_environment_id' => param['value'] }
192
-
193
- when 'ptable'
194
- result['ptable_id'] = param['value']
195
-
196
- when 'puppetenv'
197
- result['environment_id'] = param['value']
198
-
199
- when 'password'
200
- result['root_pass'] = param['value']
201
-
86
+ def configure
87
+ app_configurator = ForemanAcd::AppConfigurator.new(@app_instance)
88
+ jobs = app_configurator.configure
89
+ job_count = jobs.count
90
+
91
+ customize_first = if params[:customize] == 'true'
92
+ true
93
+ else
94
+ false
95
+ end
96
+
97
+ logger.debug("Created #{job_count} to configure #{@app_instance} - customize: #{customize_first}")
98
+
99
+ if job_count == 1 && customize_first == false
100
+ jobs.first.trigger!
101
+ redirect_to job_invocation_path(jobs.first.job_invocation)
102
+ elsif customize_first == false
103
+ jobs.each do |composer|
104
+ composer.save
202
105
  end
106
+ # redirect to the job itself if we want to customize the job
107
+ redirect_to job_invocations_path
108
+ else
109
+ # redirect to the job itself if we only have one job, otherwise to the index page
110
+ redirect_to job_invocations_path
203
111
  end
204
- result
205
112
  end
206
113
  end
207
114
  end