foreman_acd 0.0.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) 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_definitions_controller.rb +1 -2
  5. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +54 -0
  6. data/app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb +0 -0
  7. data/app/controllers/foreman_acd/app_definitions_controller.rb +35 -4
  8. data/app/controllers/foreman_acd/app_instances_controller.rb +43 -87
  9. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +23 -0
  10. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  11. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  12. data/app/controllers/ui_acd_controller.rb +11 -4
  13. data/app/models/foreman_acd/ansible_playbook.rb +50 -0
  14. data/app/models/foreman_acd/app_definition.rb +2 -1
  15. data/app/models/foreman_acd/app_instance.rb +7 -0
  16. data/app/services/foreman_acd/app_configurator.rb +70 -0
  17. data/app/services/foreman_acd/app_deployer.rb +143 -0
  18. data/app/services/foreman_acd/inventory_creator.rb +67 -0
  19. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +21 -0
  20. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +3 -0
  21. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  22. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  23. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +3 -0
  24. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +3 -0
  25. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +3 -0
  26. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +3 -0
  27. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +3 -0
  28. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +3 -0
  29. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -0
  30. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +3 -0
  31. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +3 -0
  32. data/app/views/foreman_acd/app_definitions/_form.html.erb +25 -19
  33. data/app/views/foreman_acd/app_definitions/edit.html.erb +5 -0
  34. data/app/views/foreman_acd/app_definitions/import.html.erb +18 -0
  35. data/app/views/foreman_acd/app_definitions/index.html.erb +9 -5
  36. data/app/views/foreman_acd/app_instances/_form.html.erb +10 -8
  37. data/app/views/foreman_acd/app_instances/deploy.html.erb +19 -0
  38. data/app/views/foreman_acd/app_instances/index.html.erb +10 -5
  39. data/app/views/foreman_acd/app_instances/report.html.erb +19 -0
  40. data/app/views/templates/job/run_acd_ansible_playbook.erb +49 -0
  41. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  42. data/app/views/ui_acd/app.json.rabl +6 -2
  43. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  44. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  45. data/config/routes.rb +31 -1
  46. data/db/migrate/20190610202252_create_app_definitions.rb +1 -3
  47. data/db/migrate/20190625140305_create_app_instances.rb +1 -1
  48. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  49. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  50. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +5 -0
  51. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +5 -0
  52. data/db/seeds.d/75-job_templates.rb +8 -0
  53. data/lib/foreman_acd/engine.rb +3 -0
  54. data/lib/foreman_acd/plugin.rb +72 -4
  55. data/lib/foreman_acd/version.rb +1 -1
  56. data/package.json +2 -1
  57. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +376 -0
  58. data/webpack/components/ApplicationDefinition/ApplicationDefinition.scss +1 -0
  59. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +295 -0
  60. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +14 -0
  61. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  62. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +243 -0
  63. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +8 -0
  64. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  65. data/webpack/components/ApplicationDefinition/index.js +33 -0
  66. data/webpack/components/ApplicationInstance/ApplicationInstance.js +412 -0
  67. data/webpack/components/ApplicationInstance/ApplicationInstance.scss +11 -0
  68. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +239 -0
  69. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +14 -0
  70. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +295 -0
  71. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +9 -0
  72. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +49 -0
  73. data/webpack/components/ApplicationInstance/components/Service.js +30 -0
  74. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +37 -0
  75. data/webpack/components/ApplicationInstance/index.js +35 -0
  76. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +155 -0
  77. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +27 -0
  78. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +86 -0
  79. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +4 -0
  80. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +52 -0
  81. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +5 -0
  82. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +26 -0
  83. data/webpack/components/ApplicationInstanceReport/index.js +27 -0
  84. data/webpack/components/ParameterSelection/ParameterSelection.js +96 -183
  85. data/webpack/components/ParameterSelection/ParameterSelection.scss +10 -3
  86. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +72 -104
  87. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +14 -19
  88. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +3 -35
  89. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +100 -83
  90. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +3 -7
  91. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +12 -21
  92. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +1 -1
  93. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +3 -45
  94. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +20 -0
  95. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +22 -46
  96. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  97. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +40 -265
  98. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +11 -96
  99. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +3 -9
  100. data/webpack/components/ParameterSelection/index.js +6 -8
  101. data/webpack/components/common/AddTableEntry.js +30 -0
  102. data/webpack/components/common/DeleteTableEntry.js +39 -0
  103. data/webpack/components/common/ExtSelect.js +43 -0
  104. data/webpack/components/common/RailsData.js +27 -0
  105. data/webpack/components/common/__tests__/AddTableEntry.test.js +26 -0
  106. data/webpack/components/common/__tests__/DeleteTableEntry.test.js +29 -0
  107. data/webpack/components/common/__tests__/ExtSelect.test.js +38 -0
  108. data/webpack/components/common/__tests__/RailsData.test.js +16 -0
  109. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +35 -0
  110. data/webpack/components/common/__tests__/__snapshots__/AddTableEntry.test.js.snap +35 -0
  111. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +41 -0
  112. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +41 -0
  113. data/webpack/components/common/__tests__/__snapshots__/ExtSelect.test.js.snap +18 -0
  114. data/webpack/components/common/__tests__/__snapshots__/RailsData.test.js.snap +10 -0
  115. data/webpack/helper.js +20 -0
  116. data/webpack/index.js +6 -0
  117. data/webpack/reducer.js +43 -3
  118. metadata +85 -39
@@ -0,0 +1,11 @@
1
+ @import '~@theforeman/vendor/scss/variables';
2
+
3
+ .service-counter {
4
+ position: absolute;
5
+ right: 200px;
6
+ top: 220px;
7
+ }
8
+
9
+ .service-counter-title {
10
+ font-size: 14px;
11
+ }
@@ -0,0 +1,239 @@
1
+ import React from 'react';
2
+ import api from 'foremanReact/API';
3
+ import {
4
+ setModalOpen,
5
+ setModalClosed,
6
+ } from 'foremanReact/components/ForemanModal/ForemanModalActions';
7
+
8
+ import {
9
+ actionHeaderCellFormatter,
10
+ } from 'patternfly-react';
11
+
12
+ import {
13
+ propsToSnakeCase,
14
+ propsToCamelCase,
15
+ } from 'foremanReact/common/helpers';
16
+
17
+ import {
18
+ APPLICATION_INSTANCE_INIT,
19
+ APPLICATION_INSTANCE_HOST_DELETE,
20
+ APPLICATION_INSTANCE_HOST_ADD,
21
+ APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE,
22
+ APPLICATION_INSTANCE_HOST_EDIT_CONFIRM,
23
+ APPLICATION_INSTANCE_HOST_EDIT_CHANGE,
24
+ APPLICATION_INSTANCE_HOST_EDIT_CANCEL,
25
+ APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
26
+ APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
27
+ APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
28
+ APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
29
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST,
30
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS,
31
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE,
32
+ } from './ApplicationInstanceConstants';
33
+
34
+ export const initApplicationInstance = (
35
+ appDefinition,
36
+ hosts,
37
+ ansibleVarsAll,
38
+ headerFormatter,
39
+ inlineEditFormatter,
40
+ inlineEditButtonsFormatter,
41
+ ) => dispatch => {
42
+ const initialState = {};
43
+
44
+ initialState.columns = [
45
+ {
46
+ property: 'hostname',
47
+ header: {
48
+ label: 'Hostname',
49
+ formatters: [headerFormatter],
50
+ props: {
51
+ index: 0,
52
+ style: {
53
+ width: '20%'
54
+ }
55
+ },
56
+ },
57
+ cell: {
58
+ formatters: [inlineEditFormatter]
59
+ }
60
+ },
61
+ {
62
+ property: 'description',
63
+ header: {
64
+ label: 'Description',
65
+ formatters: [headerFormatter],
66
+ props: {
67
+ index: 1,
68
+ style: {
69
+ width: '20%'
70
+ }
71
+ },
72
+ },
73
+ cell: {
74
+ formatters: [inlineEditFormatter]
75
+ }
76
+ },
77
+ {
78
+ property: 'service',
79
+ header: {
80
+ label: 'Service',
81
+ formatters: [headerFormatter],
82
+ props: {
83
+ index: 2,
84
+ style: {
85
+ width: '20%'
86
+ }
87
+ },
88
+ },
89
+ cell: {
90
+ formatters: [inlineEditFormatter]
91
+ }
92
+ },
93
+ {
94
+ property: 'actions',
95
+ header: {
96
+ label: 'Actions',
97
+ formatters: [actionHeaderCellFormatter],
98
+ props: {
99
+ index: 4,
100
+ style: {
101
+ width: '20%'
102
+ }
103
+ },
104
+ },
105
+ cell: {
106
+ formatters: [inlineEditButtonsFormatter]
107
+ }
108
+ }
109
+ ];
110
+
111
+ initialState.appDefinition = appDefinition;
112
+ initialState.hosts = hosts;
113
+ initialState.ansibleVarsAll = ansibleVarsAll;
114
+
115
+ dispatch({
116
+ type: APPLICATION_INSTANCE_INIT,
117
+ payload: initialState,
118
+ });
119
+ };
120
+
121
+ const errorHandler = (msg, err) => {
122
+ const error = {
123
+ errorMsg: 'Failed to fetch data from server.',
124
+ statusText: err,
125
+ };
126
+ return { type: msg, payload: { error } };
127
+ };
128
+
129
+ export const loadApplicationDefinition = (
130
+ applicationDefinitionId,
131
+ additionalData,
132
+ ) => dispatch => {
133
+ dispatch({ type: APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST });
134
+
135
+ const realUrl = additionalData.url.replace("__id__", applicationDefinitionId);
136
+
137
+ return api
138
+ .get(realUrl, {}, {})
139
+ .then(({ data }) =>
140
+ dispatch({
141
+ type: APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS,
142
+ payload: data,
143
+ })
144
+ )
145
+ .catch(error => dispatch(errorHandler(APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE, error)));
146
+ };
147
+
148
+ export const addApplicationInstanceHost = (additionalData) => ({
149
+ type: APPLICATION_INSTANCE_HOST_ADD,
150
+ payload: {
151
+ ...additionalData,
152
+ },
153
+ });
154
+
155
+ export const deleteApplicationInstanceHost = (additionalData) => ({
156
+ type: APPLICATION_INSTANCE_HOST_DELETE,
157
+ payload: {
158
+ ...additionalData,
159
+ },
160
+ });
161
+
162
+ export const activateEditApplicationInstanceHost = (additionalData) => ({
163
+ type: APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE,
164
+ payload: {
165
+ ...additionalData,
166
+ },
167
+ });
168
+
169
+ export const confirmEditApplicationInstanceHost = (rowData) => ({
170
+ type: APPLICATION_INSTANCE_HOST_EDIT_CONFIRM,
171
+ payload: {
172
+ ...rowData,
173
+ },
174
+ });
175
+
176
+ export const cancelEditApplicationInstanceHost = (rowData) => ({
177
+ type: APPLICATION_INSTANCE_HOST_EDIT_CANCEL,
178
+ payload: {
179
+ ...rowData,
180
+ },
181
+ });
182
+
183
+ export const changeEditApplicationInstanceHost = (value, additionalData) => ({
184
+ type: APPLICATION_INSTANCE_HOST_EDIT_CHANGE,
185
+ payload: {
186
+ value,
187
+ ...additionalData,
188
+ },
189
+ });
190
+
191
+ export const openForemanParameterSelectionModal = (additionalData) => dispatch => {
192
+ dispatch({
193
+ type: APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
194
+ payload: {
195
+ ...additionalData,
196
+ }
197
+ });
198
+ dispatch(
199
+ setModalOpen({ id: 'AppInstanceForemanParamSelection' })
200
+ );
201
+ }
202
+
203
+ export const closeForemanParameterSelectionModal = (additionalData) => dispatch => {
204
+ dispatch({
205
+ type: APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
206
+ payload: {
207
+ ...additionalData,
208
+ }
209
+ });
210
+
211
+ dispatch(
212
+ setModalClosed({ id: 'AppInstanceForemanParamSelection' })
213
+ );
214
+ }
215
+
216
+ export const openAnsibleParameterSelectionModal = (additionalData) => dispatch => {
217
+ dispatch({
218
+ type: APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
219
+ payload: {
220
+ ...additionalData,
221
+ }
222
+ });
223
+ dispatch(
224
+ setModalOpen({ id: 'AppInstanceAnsibleParamSelection' })
225
+ );
226
+ }
227
+
228
+ export const closeAnsibleParameterSelectionModal = (additionalData) => dispatch => {
229
+ dispatch({
230
+ type: APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
231
+ payload: {
232
+ ...additionalData,
233
+ }
234
+ });
235
+
236
+ dispatch(
237
+ setModalClosed({ id: 'AppInstanceAnsibleParamSelection' })
238
+ );
239
+ }
@@ -0,0 +1,14 @@
1
+ export const APPLICATION_INSTANCE_INIT = 'APPLICATION_INSTANCE_INIT';
2
+ export const APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST = 'APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST';
3
+ export const APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS = 'APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS';
4
+ export const APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE = 'APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE';
5
+ export const APPLICATION_INSTANCE_HOST_DELETE = 'APPLICATION_INSTANCE_HOST_DELETE';
6
+ export const APPLICATION_INSTANCE_HOST_ADD = 'APPLICATION_INSTANCE_HOST_ADD';
7
+ export const APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE = 'APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE';
8
+ export const APPLICATION_INSTANCE_HOST_EDIT_CONFIRM = 'APPLICATION_INSTANCE_HOST_EDIT_CONFIRM';
9
+ export const APPLICATION_INSTANCE_HOST_EDIT_CHANGE = 'APPLICATION_INSTANCE_HOST_EDIT_CHANGE';
10
+ export const APPLICATION_INSTANCE_HOST_EDIT_CANCEL = 'APPLICATION_INSTANCE_HOST_EDIT_CANCEL';
11
+ export const APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN = 'APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN';
12
+ export const APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE = 'APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE';
13
+ export const APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN = 'APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN';
14
+ export const APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE = 'APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE';
@@ -0,0 +1,295 @@
1
+ import Immutable from 'seamless-immutable';
2
+
3
+ import {
4
+ cloneDeep,
5
+ findIndex,
6
+ findLastIndex,
7
+ } from 'lodash';
8
+
9
+ import {
10
+ APPLICATION_INSTANCE_INIT,
11
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE,
12
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST,
13
+ APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS,
14
+ APPLICATION_INSTANCE_HOST_DELETE,
15
+ APPLICATION_INSTANCE_HOST_ADD,
16
+ APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE,
17
+ APPLICATION_INSTANCE_HOST_EDIT_CONFIRM,
18
+ APPLICATION_INSTANCE_HOST_EDIT_CHANGE,
19
+ APPLICATION_INSTANCE_HOST_EDIT_CANCEL,
20
+ APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
21
+ APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
22
+ APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
23
+ APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
24
+ } from './ApplicationInstanceConstants';
25
+
26
+ import {
27
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
28
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
29
+ } from '../ParameterSelection/ParameterSelectionConstants';
30
+
31
+ export const initialState = Immutable({
32
+ name: false,
33
+ error: { errorMsg: '', status: '', statusText: '' },
34
+ });
35
+
36
+ const applicationInstanceConf = (state = initialState, action) => {
37
+ const { payload } = action;
38
+
39
+ switch (action.type) {
40
+ case APPLICATION_INSTANCE_INIT: {
41
+ return state.merge(payload);
42
+ }
43
+ case APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_FAILURE: {
44
+ return state.merge({ error: payload.error, loading: false });
45
+ }
46
+ case APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_REQUEST: {
47
+ return state.set('loading', true);
48
+ }
49
+ case APPLICATION_INSTANCE_LOAD_APPLICATION_DEFINITION_SUCCESS: {
50
+ let newState = {};
51
+ const services = JSON.parse(payload.app_definition.services);
52
+
53
+ // initialize all services count with 0
54
+ services.map(serv => {
55
+ serv['currentCount'] = 0;
56
+ })
57
+
58
+ // Update count
59
+ if (state.hosts !== undefined) {
60
+ state.hosts.map((host, index) => {
61
+ const hostServiceId = Number(host.service);
62
+ const service = services.find(serv => serv['id'] == hostServiceId);
63
+ service['currentCount'] += 1;
64
+ });
65
+ }
66
+
67
+ newState = {
68
+ appDefinition: payload.app_definition,
69
+ services: services,
70
+ loading: false,
71
+ };
72
+
73
+ // Initialize ansibleVarsAll if there is no data available in app instance
74
+ if (state.ansibleVarsAll.length <= 0) {
75
+ newState['ansibleVarsAll'] = JSON.parse(payload.app_definition.ansible_vars_all);
76
+ }
77
+
78
+ return state.merge(newState);
79
+ }
80
+ case APPLICATION_INSTANCE_HOST_ADD: {
81
+ let hosts = [];
82
+ let index = 1;
83
+
84
+ if ('hosts' in state && state.hosts !== undefined && state.hosts.length > 0) {
85
+ hosts = cloneDeep(state.hosts);
86
+ index = Math.max(...hosts.map(e => e.id)) + 1;
87
+ }
88
+
89
+ const newRow = {id: index, hostname: "", description: '', service: '', foremanParameters: [], ansibleParameters: [], newEntry: true };
90
+ newRow.backup = cloneDeep(newRow)
91
+ hosts.push(newRow);
92
+
93
+ return state.merge({
94
+ editMode: true,
95
+ hosts: hosts
96
+ });
97
+ }
98
+ case APPLICATION_INSTANCE_HOST_DELETE: {
99
+ const services = cloneDeep(state.services);
100
+ const host = state.hosts.find(v => v.id == payload.rowData.id);
101
+ const hostServiceId = Number(host.service);
102
+ const hosts = state.hosts.filter(v => v.id !== host.id);
103
+
104
+ // Update count
105
+ const service = services.find(serv => serv['id'] == hostServiceId);
106
+ service['currentCount'] -= 1;
107
+
108
+ return state.merge({
109
+ hosts: hosts,
110
+ services: services,
111
+ })
112
+ }
113
+ case APPLICATION_INSTANCE_HOST_EDIT_ACTIVATE: {
114
+ const hosts = cloneDeep(state.hosts);
115
+ const index = findIndex(hosts, { id: payload.rowData.id });
116
+
117
+ hosts[index].backup = cloneDeep(hosts[index]);
118
+
119
+ return state.merge({
120
+ editMode: true,
121
+ hosts: hosts
122
+ });
123
+ }
124
+ case APPLICATION_INSTANCE_HOST_EDIT_CONFIRM: {
125
+ const hosts = cloneDeep(state.hosts);
126
+ const index = findIndex(hosts, { id: payload.rowData.id });
127
+ const services = cloneDeep(state.services);
128
+
129
+ const thisHost = hosts[index];
130
+
131
+ if (thisHost.hostname == '') {
132
+ window.alert("Every host needs to have a valid name");
133
+ return state;
134
+ }
135
+
136
+ if (thisHost.service == '') {
137
+ window.alert("Every host needs to be assigned to a service");
138
+ return state;
139
+ }
140
+
141
+ if (state.hosts.filter(v => v.hostname === thisHost.hostname && v.id != thisHost.id).length > 0) {
142
+ window.alert("Host name already used for this Application Instance. Please make sure that every host name is unique");
143
+ return state;
144
+ }
145
+
146
+ // Initialize the new Instance with the parameters of the Application Definition.
147
+ if (thisHost.newEntry === true) {
148
+ const selectedService = state.services.filter(entry => entry.id == payload.rowData.service)[0];
149
+ hosts[index].foremanParameters = selectedService.foremanParameters;
150
+ hosts[index].ansibleParameters = selectedService.ansibleParameters;
151
+
152
+ const hostServiceId = Number(thisHost.service);
153
+ const service = services.find(serv => serv['id'] == hostServiceId);
154
+ if ('currentCount' in service) {
155
+ service['currentCount'] += 1;
156
+ } else {
157
+ service['currentCount'] = 1;
158
+ }
159
+ }
160
+
161
+ delete hosts[index].backup;
162
+ delete hosts[index].newEntry;
163
+
164
+ return state.merge({
165
+ editMode: false,
166
+ services: services,
167
+ hosts: hosts
168
+ });
169
+ }
170
+ case APPLICATION_INSTANCE_HOST_EDIT_CHANGE: {
171
+ const hosts = cloneDeep(state.hosts);
172
+ const index = findIndex(hosts, { id: payload.rowData.id });
173
+
174
+ hosts[index][payload.property] = payload.value;
175
+
176
+ return state.set('hosts', hosts);
177
+ }
178
+ case APPLICATION_INSTANCE_HOST_EDIT_CANCEL: {
179
+ const hosts = cloneDeep(state.hosts);
180
+ const index = findIndex(hosts, { id: payload.rowData.id });
181
+
182
+ hosts[index] = cloneDeep(hosts[index].backup);
183
+ delete hosts[index].backup;
184
+
185
+ if (hosts[index].newEntry === true) {
186
+ hosts.splice(index, 1);
187
+ }
188
+
189
+ return state.merge({
190
+ editMode: false,
191
+ hosts: hosts
192
+ });
193
+ }
194
+ case APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN: {
195
+ let parametersData = {};
196
+
197
+ const selectedService = state.services.filter(entry => entry.id == payload.rowData.service)[0];
198
+
199
+ parametersData.paramDefinition = {
200
+ id: selectedService.id,
201
+ name: selectedService.name,
202
+ dataId: selectedService.hostgroup,
203
+ hostId: payload.rowData.id,
204
+ // TODO: is this really correct? Guess it shoud be dataId and we should get rid of them
205
+ //hostgroup_id: selectedService.hostgroup,
206
+ };
207
+ parametersData.type = PARAMETER_SELECTION_PARAM_TYPE_FOREMAN;
208
+ parametersData.parameters = payload.rowData.foremanParameters;
209
+ parametersData.useDefaultValue = false;
210
+ parametersData.allowRowAdjustment = false;
211
+ parametersData.allowNameAdjustment = false;
212
+ parametersData.allowDescriptionAdjustment = false;
213
+
214
+ return state.merge({
215
+ parametersData: parametersData,
216
+ });
217
+ }
218
+ case APPLICATION_INSTANCE_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE: {
219
+ if (payload.mode == 'save') {
220
+ const hosts = cloneDeep(state.hosts);
221
+ const index = findIndex(hosts, { id: state.parametersData.paramDefinition.hostId });
222
+ hosts[index].foremanParameters = cloneDeep(payload.parameterSelection);
223
+
224
+ return state.merge({
225
+ parametersData: null,
226
+ hosts: hosts
227
+ });
228
+ } else {
229
+ return state.merge({
230
+ parametersData: null,
231
+ });
232
+ }
233
+ }
234
+ case APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN: {
235
+ let parametersData = {};
236
+
237
+ if ((payload.hasOwnProperty('isAllGroup')) && (payload.isAllGroup == true)) {
238
+ parametersData.parameters = state.ansibleVarsAll;
239
+ parametersData.paramDefinition = {
240
+ isAllGroup: true,
241
+ }
242
+ } else {
243
+ const selectedService = state.services.filter(entry => entry.id == payload.rowData.service)[0];
244
+
245
+ parametersData.paramDefinition = {
246
+ id: selectedService.id,
247
+ name: selectedService.name,
248
+ hostId: payload.rowData.id,
249
+ // TODO: is this really correct? Guess it shoud be dataId and we should get rid of them
250
+ //hostgroup_id: selectedService.hostgroup,
251
+ };
252
+ parametersData.parameters = payload.rowData.ansibleParameters;
253
+ }
254
+
255
+ parametersData.type = PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE;
256
+ parametersData.useDefaultValue = false;
257
+ parametersData.allowRowAdjustment = false;
258
+ parametersData.allowNameAdjustment = false;
259
+ parametersData.allowDescriptionAdjustment = false;
260
+
261
+ return state.merge({
262
+ parametersData: parametersData,
263
+ });
264
+ }
265
+ case APPLICATION_INSTANCE_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE: {
266
+ let newState = {};
267
+ if (payload.mode == 'save') {
268
+ if ((state.parametersData.paramDefinition.hasOwnProperty('isAllGroup')) && (state.parametersData.paramDefinition.isAllGroup == true)) {
269
+ newState = {
270
+ parametersData: null,
271
+ ansibleVarsAll: cloneDeep(payload.parameterSelection),
272
+ };
273
+ } else {
274
+ const hosts = cloneDeep(state.hosts);
275
+ const index = findIndex(hosts, { id: state.parametersData.paramDefinition.hostId });
276
+ hosts[index].ansibleParameters = cloneDeep(payload.parameterSelection);
277
+
278
+ newState = {
279
+ parametersData: null,
280
+ hosts: hosts
281
+ };
282
+ }
283
+ } else {
284
+ newState = {
285
+ parametersData: null,
286
+ };
287
+ }
288
+ return state.merge(newState);
289
+ }
290
+ default:
291
+ return state;
292
+ }
293
+ };
294
+
295
+ export default applicationInstanceConf;