foreman_acd 0.0.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +82 -27
  3. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +122 -0
  4. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +71 -0
  5. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +1 -2
  6. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +54 -0
  7. data/app/controllers/foreman_acd/api/v2/app_playbooks_controller.rb +0 -0
  8. data/app/controllers/foreman_acd/app_definitions_controller.rb +36 -4
  9. data/app/controllers/foreman_acd/app_instances_controller.rb +24 -90
  10. data/app/controllers/foreman_acd/concerns/ansible_playbook_parameters.rb +23 -0
  11. data/app/controllers/foreman_acd/concerns/app_definition_parameters.rb +1 -1
  12. data/app/controllers/foreman_acd/concerns/app_instance_parameters.rb +1 -1
  13. data/app/controllers/foreman_acd/remote_execution_controller.rb +49 -0
  14. data/app/controllers/ui_acd_controller.rb +11 -4
  15. data/app/models/foreman_acd/acd_provider.rb +27 -0
  16. data/app/models/foreman_acd/ansible_playbook.rb +50 -0
  17. data/app/models/foreman_acd/app_definition.rb +2 -1
  18. data/app/models/foreman_acd/app_instance.rb +7 -0
  19. data/app/services/foreman_acd/app_configurator.rb +57 -0
  20. data/app/services/foreman_acd/app_deployer.rb +139 -0
  21. data/app/services/foreman_acd/inventory_creator.rb +67 -0
  22. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +21 -0
  23. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +3 -0
  24. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  25. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  26. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +3 -0
  27. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +3 -0
  28. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +3 -0
  29. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +3 -0
  30. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +3 -0
  31. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +3 -0
  32. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +3 -0
  33. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +3 -0
  34. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +3 -0
  35. data/app/views/foreman_acd/app_definitions/_form.html.erb +25 -19
  36. data/app/views/foreman_acd/app_definitions/edit.html.erb +5 -0
  37. data/app/views/foreman_acd/app_definitions/import.html.erb +18 -0
  38. data/app/views/foreman_acd/app_definitions/index.html.erb +9 -5
  39. data/app/views/foreman_acd/app_instances/_form.html.erb +10 -8
  40. data/app/views/foreman_acd/app_instances/deploy.html.erb +19 -0
  41. data/app/views/foreman_acd/app_instances/index.html.erb +10 -5
  42. data/app/views/foreman_acd/app_instances/report.html.erb +19 -0
  43. data/app/views/templates/job/run_acd_ansible_playbook.erb +49 -0
  44. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  45. data/app/views/ui_acd/app.json.rabl +6 -2
  46. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  47. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  48. data/config/routes.rb +36 -1
  49. data/db/migrate/20190610202252_create_app_definitions.rb +1 -3
  50. data/db/migrate/20190625140305_create_app_instances.rb +1 -1
  51. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  52. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  53. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +5 -0
  54. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +5 -0
  55. data/db/seeds.d/62_acd_proxy_feature.rb +6 -0
  56. data/db/seeds.d/75-job_templates.rb +8 -0
  57. data/lib/foreman_acd/engine.rb +7 -0
  58. data/lib/foreman_acd/plugin.rb +84 -13
  59. data/lib/foreman_acd/version.rb +1 -1
  60. data/package.json +1 -2
  61. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +378 -0
  62. data/webpack/components/ApplicationDefinition/ApplicationDefinition.scss +1 -0
  63. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +295 -0
  64. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +14 -0
  65. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  66. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +243 -0
  67. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +8 -0
  68. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  69. data/webpack/components/ApplicationDefinition/index.js +33 -0
  70. data/webpack/components/ApplicationInstance/ApplicationInstance.js +414 -0
  71. data/webpack/components/ApplicationInstance/ApplicationInstance.scss +11 -0
  72. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +239 -0
  73. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +14 -0
  74. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +295 -0
  75. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +9 -0
  76. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +49 -0
  77. data/webpack/components/ApplicationInstance/components/Service.js +30 -0
  78. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +37 -0
  79. data/webpack/components/ApplicationInstance/index.js +35 -0
  80. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +155 -0
  81. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +27 -0
  82. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +86 -0
  83. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +4 -0
  84. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +52 -0
  85. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +5 -0
  86. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +26 -0
  87. data/webpack/components/ApplicationInstanceReport/index.js +27 -0
  88. data/webpack/components/ParameterSelection/ParameterSelection.js +121 -192
  89. data/webpack/components/ParameterSelection/ParameterSelection.scss +9 -0
  90. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +80 -104
  91. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +15 -19
  92. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +3 -35
  93. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +116 -84
  94. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +3 -7
  95. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +12 -21
  96. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +1 -1
  97. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +3 -45
  98. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +20 -0
  99. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +22 -46
  100. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  101. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +40 -265
  102. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +11 -96
  103. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +3 -9
  104. data/webpack/components/ParameterSelection/index.js +6 -8
  105. data/webpack/components/common/AddTableEntry.js +30 -0
  106. data/webpack/components/common/DeleteTableEntry.js +38 -0
  107. data/webpack/components/common/EasyHeaderFormatter.js +18 -0
  108. data/webpack/components/common/EditTableEntry.js +49 -0
  109. data/webpack/components/common/ExtSelect.js +43 -0
  110. data/webpack/components/common/LockTableEntry.js +59 -0
  111. data/webpack/components/common/RailsData.js +27 -0
  112. data/webpack/components/common/__tests__/AddTableEntry.test.js +26 -0
  113. data/webpack/components/common/__tests__/DeleteTableEntry.test.js +29 -0
  114. data/webpack/components/common/__tests__/ExtSelect.test.js +38 -0
  115. data/webpack/components/common/__tests__/RailsData.test.js +16 -0
  116. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +35 -0
  117. data/webpack/components/common/__tests__/__snapshots__/AddTableEntry.test.js.snap +35 -0
  118. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +41 -0
  119. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +41 -0
  120. data/webpack/components/common/__tests__/__snapshots__/ExtSelect.test.js.snap +18 -0
  121. data/webpack/components/common/__tests__/__snapshots__/RailsData.test.js.snap +10 -0
  122. data/webpack/helper.js +20 -0
  123. data/webpack/index.js +6 -0
  124. data/webpack/reducer.js +43 -3
  125. metadata +91 -39
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ForemanAcd
4
- VERSION = '0.0.5'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreman_acd",
3
- "version": "0.0.5",
3
+ "version": "0.3.0",
4
4
  "description": "foreman application centric deployment",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -31,7 +31,6 @@
31
31
  "eslint-plugin-react": "^7.4.0",
32
32
  "identity-obj-proxy": "^3.0.0",
33
33
  "lodash": "^4.17.11",
34
- "patternfly-react": "^2.31.0",
35
34
  "jest": "^23.6.0",
36
35
  "jest-cli": "^23.6.0",
37
36
  "jest-prop-type-error": "^1.1.0",
@@ -0,0 +1,378 @@
1
+ import $ from 'jquery';
2
+ import React, { useState } from 'react'
3
+ import PropTypes from 'prop-types';
4
+ import {
5
+ Icon,
6
+ Button,
7
+ } from 'patternfly-react';
8
+ import * as resolve from 'table-resolver';
9
+ import ForemanModal from 'foremanReact/components/ForemanModal';
10
+ import Select from 'foremanReact/components/common/forms/Select';
11
+ import ParameterSelection from '../ParameterSelection';
12
+ import AddTableEntry from '../common/AddTableEntry';
13
+ import DeleteTableEntry from '../common/DeleteTableEntry';
14
+ import RailsData from '../common/RailsData';
15
+ import EasyHeaderFormatter from '../common/EasyHeaderFormatter';
16
+ import AnsiblePlaybookSelector from './components/AnsiblePlaybookSelector';
17
+
18
+ import {
19
+ Table,
20
+ FormControl,
21
+ inlineEditFormatterFactory,
22
+ } from 'patternfly-react';
23
+
24
+ import {
25
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
26
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
27
+ } from '../ParameterSelection/ParameterSelectionConstants';
28
+
29
+ class ApplicationDefinition extends React.Component {
30
+
31
+ constructor(props) {
32
+ super(props);
33
+ }
34
+
35
+ isEditing({rowData}) {
36
+ return (rowData.backup !== undefined);
37
+ }
38
+
39
+ createAnsibleGroupObject(ansibleGroups, withAll=false) {
40
+ const ansibleGroupObj = {};
41
+
42
+ const ansibleGroupArray = Object.keys(ansibleGroups);
43
+ ansibleGroupArray.forEach(e => (ansibleGroupObj[e] = e));
44
+
45
+ if ((withAll === false) && (ansibleGroupObj.hasOwnProperty('all'))) {
46
+ delete ansibleGroupObj.all;
47
+ }
48
+
49
+ return ansibleGroupObj;
50
+ }
51
+
52
+ componentDidMount() {
53
+ const {
54
+ data: { mode, ansiblePlaybook, ansibleDataUrl, services, ansibleVarsAll, hostgroups },
55
+ initApplicationDefinition,
56
+ addApplicationDefinitionService,
57
+ deleteApplicationDefinitionService,
58
+ activateEditApplicationDefinitionService,
59
+ changeEditApplicationDefinitionService,
60
+ openForemanParameterSelectionModal,
61
+ openAnsibleParameterSelectionModal,
62
+ loadAnsibleData,
63
+ } = this.props;
64
+
65
+ const inlineEditButtonsFormatter = inlineEditFormatterFactory({
66
+ isEditing: additionalData => this.props.editMode,
67
+ renderValue: (value, additionalData) => (
68
+ <td style={{ padding: '2px' }}>
69
+ <Button
70
+ bsStyle="default"
71
+ onClick={() => activateEditApplicationDefinitionService(additionalData)}
72
+ >
73
+ <Icon type="pf" name="edit" title="edit entry" />
74
+ </Button>
75
+ &nbsp;
76
+ <Button
77
+ bsStyle="default"
78
+ onClick={() => openForemanParameterSelectionModal(additionalData)}
79
+ >
80
+ <Icon type="pf" name="settings" title="change parameters" />
81
+ </Button>
82
+ &nbsp;
83
+ <Button
84
+ bsStyle="default"
85
+ onClick={() => openAnsibleParameterSelectionModal(additionalData)}
86
+ >
87
+ <span title="change ansible variables">A</span>
88
+ </Button>
89
+ &nbsp;
90
+ <DeleteTableEntry
91
+ hidden={false}
92
+ disabled={false}
93
+ onDeleteTableEntry={deleteApplicationDefinitionService}
94
+ additionalData={additionalData}
95
+ />
96
+ </td>
97
+ ),
98
+ renderEdit: (value, additionalData) => (
99
+ <td style={{ padding: '2px' }}>
100
+ <Button bsStyle="default" disabled>
101
+ <Icon type="pf" name="edit" />
102
+ </Button>
103
+ &nbsp;
104
+ <Button bsStyle="default" disabled>
105
+ <Icon type="pf" name="settings" />
106
+ </Button>
107
+ &nbsp;
108
+ <Button
109
+ bsStyle="default" disabled>
110
+ <span>A</span>
111
+ </Button>
112
+ &nbsp;
113
+ <DeleteTableEntry
114
+ hidden={false}
115
+ disabled={true}
116
+ onDeleteTableEntry={deleteApplicationDefinitionService}
117
+ additionalData={additionalData}
118
+ />
119
+ </td>
120
+ )
121
+ });
122
+ this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
123
+
124
+ this.headerFormatter = EasyHeaderFormatter;
125
+
126
+ const inlineEditFormatterImpl = {
127
+ renderValue: (value, additionalData) => (
128
+ <td>
129
+ <span className="static">{value}</span>
130
+ </td>
131
+ ),
132
+ renderEditText: (value, additionalData, subtype='text') => (
133
+ <td className="editing">
134
+ <FormControl
135
+ type={subtype}
136
+ defaultValue={value}
137
+ onBlur={e => changeEditApplicationDefinitionService(e.target.value, additionalData) }
138
+ />
139
+ </td>
140
+ ),
141
+ renderEditSelect: (value, additionalData, options) => (
142
+ <td className="editing">
143
+ <Select
144
+ value={value.toString()}
145
+ onChange={e => changeEditApplicationDefinitionService(e.target.value, additionalData) }
146
+ options={options}
147
+ allowClear
148
+ key="key"
149
+ />
150
+ </td>
151
+ )
152
+ };
153
+
154
+ const inlineEditFormatter = inlineEditFormatterFactory({
155
+ isEditing: additionalData => this.isEditing(additionalData),
156
+ renderValue: (value, additionalData) => {
157
+ let prettyValue = value;
158
+ if (additionalData.property == 'hostgroup') {
159
+ prettyValue = hostgroups[value];
160
+ }
161
+ else if (additionalData.property == 'ansibleGroup') {
162
+ const ag = this.createAnsibleGroupObject(this.props.ansiblePlaybook.groups);
163
+ prettyValue = ag[value];
164
+ }
165
+ return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
166
+ },
167
+ renderEdit: (value, additionalData) => {
168
+ if (additionalData.property == 'hostgroup') {
169
+ if (additionalData.rowData.newEntry === true) {
170
+ return inlineEditFormatterImpl.renderEditSelect(value, additionalData, hostgroups);
171
+ }
172
+ return inlineEditFormatterImpl.renderValue(hostgroups[value], additionalData)
173
+ }
174
+ else if (additionalData.property == 'ansibleGroup') {
175
+ const ag = this.createAnsibleGroupObject(this.props.ansiblePlaybook.groups);
176
+
177
+ if (additionalData.rowData.newEntry === true) {
178
+ return inlineEditFormatterImpl.renderEditSelect(value, additionalData, ag);
179
+ }
180
+ return inlineEditFormatterImpl.renderValue(ag[value], additionalData);
181
+ }
182
+ return inlineEditFormatterImpl.renderEditText(value, additionalData);
183
+ }
184
+ });
185
+ this.inlineEditFormatter = inlineEditFormatter;
186
+
187
+ initApplicationDefinition(
188
+ ansiblePlaybook,
189
+ services,
190
+ ansibleVarsAll,
191
+ this.headerFormatter,
192
+ this.inlineEditFormatter,
193
+ this.inlineEditButtonsFormatter,
194
+ );
195
+ };
196
+
197
+ render() {
198
+ const {
199
+ data: { organization, location, mode, ansiblePlaybooks, foremanDataUrl, ansibleDataUrl },
200
+ ansiblePlaybook,
201
+ services,
202
+ columns,
203
+ addApplicationDefinitionService,
204
+ confirmEditApplicationDefinitionService,
205
+ cancelEditApplicationDefinitionService,
206
+ closeForemanParameterSelectionModal,
207
+ openAnsibleParameterSelectionModal,
208
+ closeAnsibleParameterSelectionModal,
209
+ ParameterSelectionModal,
210
+ loadAnsibleData,
211
+ } = this.props;
212
+
213
+ return (
214
+ <span>
215
+ <div>
216
+ <AnsiblePlaybookSelector
217
+ label="Ansible Playbook"
218
+ editable={ mode == 'newDefinition' }
219
+ viewText={ ansiblePlaybook.name }
220
+ options={ ansiblePlaybooks }
221
+ onChange={ loadAnsibleData }
222
+ selectValue={ ansiblePlaybook.id.toString() }
223
+ additionalData={{url: ansibleDataUrl }}
224
+ />
225
+ </div>
226
+ <div className="form-group">
227
+ <AddTableEntry
228
+ hidden={ false }
229
+ disabled={ this.props.editMode }
230
+ onAddTableEntry={ addApplicationDefinitionService }
231
+ />
232
+ <Table.PfProvider
233
+ striped
234
+ bordered
235
+ hover
236
+ dataTable
237
+ inlineEdit
238
+ columns={columns}
239
+ components={{
240
+ body: {
241
+ row: Table.InlineEditRow,
242
+ cell: cellProps => cellProps.children
243
+ }
244
+ }}
245
+ >
246
+ <Table.Header headerRows={resolve.headerRows({ columns })} />
247
+ <Table.Body
248
+ rows={services}
249
+ rowKey="id"
250
+ onRow={(rowData, { rowIndex }) => ({
251
+ role: 'row',
252
+ isEditing: () => this.isEditing({ rowData }),
253
+ onCancel: () => cancelEditApplicationDefinitionService({ rowData, rowIndex }),
254
+ onConfirm: () => confirmEditApplicationDefinitionService({ rowData, rowIndex }),
255
+ last: rowIndex === services.length - 1
256
+ })}
257
+ />
258
+ </Table.PfProvider>
259
+ <AddTableEntry
260
+ hidden={ false }
261
+ disabled={ this.props.editMode }
262
+ onAddTableEntry={ addApplicationDefinitionService }
263
+ />
264
+ <span style={{ marginLeft: 30 }}>
265
+ Ansible group vars 'all':
266
+ <Button
267
+ style={{ marginLeft: 10 }}
268
+ bsStyle="default"
269
+ disabled={ this.props.editMode }
270
+ onClick={() => openAnsibleParameterSelectionModal({
271
+ isAllGroup: true
272
+ })}
273
+ >
274
+ <span title="change ansible variables for 'all'">A</span>
275
+ </Button>
276
+ </span>
277
+ </div>
278
+ <div>
279
+ <ForemanModal
280
+ id="AppDefinitionForemanParamSelection"
281
+ dialogClassName="param_selection_modal"
282
+ title="Foreman Parameter definition for Application Definition"
283
+ >
284
+ <ForemanModal.Header closeButton={false}>
285
+ Parameter definition
286
+ </ForemanModal.Header>
287
+ {this.props.parametersData ? (
288
+ <ParameterSelection
289
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN }
290
+ location={ location }
291
+ organization={ organization }
292
+ paramDataUrl= { foremanDataUrl }
293
+ data={ this.props.parametersData }
294
+ />
295
+ ) : (<span>Empty</span>)
296
+ }
297
+ <ForemanModal.Footer>
298
+ <div>
299
+ <Button bsStyle="primary" onClick={() => closeForemanParameterSelectionModal({ mode: 'save' })}>Save</Button>
300
+ <Button bsStyle="default" onClick={() => closeForemanParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
301
+ </div>
302
+ </ForemanModal.Footer>
303
+ </ForemanModal>
304
+ </div>
305
+ <div>
306
+ <ForemanModal
307
+ id="AppDefinitionAnsibleParamSelection"
308
+ dialogClassName="param_selection_modal"
309
+ title="Ansible variables for Application Definition"
310
+ >
311
+ <ForemanModal.Header closeButton={false}>
312
+ Parameter definition
313
+ </ForemanModal.Header>
314
+ {this.props.parametersData ? (
315
+ <ParameterSelection
316
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE }
317
+ location={ location }
318
+ organization={ organization }
319
+ data={ this.props.parametersData }
320
+ />
321
+ ) : (<span>Empty</span>)
322
+ }
323
+ <ForemanModal.Footer>
324
+ <div>
325
+ <Button bsStyle="primary" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'save' })}>Save</Button>
326
+ <Button bsStyle="default" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
327
+ </div>
328
+ </ForemanModal.Footer>
329
+ </ForemanModal>
330
+ </div>
331
+ <RailsData
332
+ key='applications_definition'
333
+ view='app_definition'
334
+ parameter='services'
335
+ value={JSON.stringify(this.props.services)}
336
+ />
337
+ <RailsData
338
+ key='applications_definition'
339
+ view='app_definition'
340
+ parameter='ansible_vars_all'
341
+ value={JSON.stringify(this.props.ansibleVarsAll)}
342
+ />
343
+ </span>
344
+ )};
345
+ }
346
+
347
+ ApplicationDefinition.defaultProps = {
348
+ error: {},
349
+ editMode: false,
350
+ ansiblePlaybook: { "id": '', "name": '' },
351
+ services: [],
352
+ ansibleVarsAll: [],
353
+ parametersData: {},
354
+ columns: [],
355
+ editParamsOfRowId: null,
356
+ }
357
+
358
+ ApplicationDefinition.propTypes = {
359
+ initApplicationDefinition: PropTypes.func,
360
+ editMode: PropTypes.bool.isRequired,
361
+ ansiblePlaybook: PropTypes.object,
362
+ services: PropTypes.array,
363
+ ansibleVarsAll: PropTypes.array,
364
+ columns: PropTypes.array,
365
+ addApplicationDefinitionService: PropTypes.func,
366
+ deleteApplicationDefinitionService: PropTypes.func,
367
+ activateEditApplicationDefinitionService: PropTypes.func,
368
+ confirmEditApplicationDefinitionService: PropTypes.func,
369
+ cancelEditApplicationDefinitionService: PropTypes.func,
370
+ changeEditApplicationDefinitionService: PropTypes.func,
371
+ openForemanParameterSelectionModal: PropTypes.func,
372
+ closeForemanParameterSelectionModal: PropTypes.func,
373
+ openAnsibleParameterSelectionModal: PropTypes.func,
374
+ closeAnsibleParameterSelectionModal: PropTypes.func,
375
+ parametersData: PropTypes.object,
376
+ };
377
+
378
+ export default ApplicationDefinition;
@@ -0,0 +1 @@
1
+ @import '~@theforeman/vendor/scss/variables';
@@ -0,0 +1,295 @@
1
+ import React from 'react';
2
+ import api from 'foremanReact/API';
3
+
4
+ import {
5
+ setModalOpen,
6
+ setModalClosed,
7
+ } from 'foremanReact/components/ForemanModal/ForemanModalActions';
8
+
9
+ import {
10
+ actionHeaderCellFormatter,
11
+ } from 'patternfly-react';
12
+
13
+ import {
14
+ propsToSnakeCase,
15
+ propsToCamelCase,
16
+ } from 'foremanReact/common/helpers';
17
+
18
+ import {
19
+ APPLICATION_DEFINITION_INIT,
20
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST,
21
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS,
22
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE,
23
+ APPLICATION_DEFINITION_SERVICE_DELETE,
24
+ APPLICATION_DEFINITION_SERVICE_ADD,
25
+ APPLICATION_DEFINITION_SERVICE_EDIT_ACTIVATE,
26
+ APPLICATION_DEFINITION_SERVICE_EDIT_CONFIRM,
27
+ APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE,
28
+ APPLICATION_DEFINITION_SERVICE_EDIT_CANCEL,
29
+ APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
30
+ APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
31
+ APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
32
+ APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
33
+ } from './ApplicationDefinitionConstants';
34
+
35
+ import {
36
+ transformAnsiblePlaybook,
37
+ } from './ApplicationDefinitionHelper';
38
+
39
+ export const initApplicationDefinition = (
40
+ ansiblePlaybook,
41
+ services,
42
+ ansibleVarsAll,
43
+ headerFormatter,
44
+ inlineEditFormatter,
45
+ inlineEditButtonsFormatter,
46
+ ) => dispatch => {
47
+ const initialState = {};
48
+
49
+ initialState.columns = [
50
+ {
51
+ property: 'name',
52
+ header: {
53
+ label: 'Name',
54
+ formatters: [headerFormatter],
55
+ props: {
56
+ index: 0,
57
+ style: {
58
+ width: '15%'
59
+ }
60
+ },
61
+ },
62
+ cell: {
63
+ formatters: [inlineEditFormatter]
64
+ }
65
+ },
66
+ {
67
+ property: 'description',
68
+ header: {
69
+ label: 'Description',
70
+ formatters: [headerFormatter],
71
+ props: {
72
+ index: 1,
73
+ style: {
74
+ width: '10%'
75
+ }
76
+ },
77
+ },
78
+ cell: {
79
+ formatters: [inlineEditFormatter]
80
+ }
81
+ },
82
+ {
83
+ property: 'hostgroup',
84
+ header: {
85
+ label: 'Hostgroup',
86
+ formatters: [headerFormatter],
87
+ props: {
88
+ index: 2,
89
+ style: {
90
+ width: '20%'
91
+ }
92
+ },
93
+ },
94
+ cell: {
95
+ formatters: [inlineEditFormatter]
96
+ }
97
+ },
98
+ {
99
+ property: 'ansibleGroup',
100
+ header: {
101
+ label: 'Ansible Group',
102
+ formatters: [headerFormatter],
103
+ props: {
104
+ index: 3,
105
+ style: {
106
+ width: '20%'
107
+ }
108
+ },
109
+ },
110
+ cell: {
111
+ formatters: [inlineEditFormatter]
112
+ }
113
+ },
114
+ {
115
+ property: 'minCount',
116
+ header: {
117
+ label: 'min count',
118
+ formatters: [headerFormatter],
119
+ props: {
120
+ index: 4,
121
+ style: {
122
+ width: '10%'
123
+ }
124
+ },
125
+ },
126
+ cell: {
127
+ formatters: [inlineEditFormatter]
128
+ }
129
+ },
130
+ {
131
+ property: 'maxCount',
132
+ header: {
133
+ label: 'max count',
134
+ formatters: [headerFormatter],
135
+ props: {
136
+ index: 5,
137
+ style: {
138
+ width: '10%'
139
+ }
140
+ },
141
+ },
142
+ cell: {
143
+ formatters: [inlineEditFormatter]
144
+ }
145
+ },
146
+ {
147
+ property: 'actions',
148
+ header: {
149
+ label: 'Actions',
150
+ formatters: [actionHeaderCellFormatter],
151
+ props: {
152
+ index: 6,
153
+ style: {
154
+ width: '15%'
155
+ }
156
+ },
157
+ },
158
+ cell: {
159
+ formatters: [inlineEditButtonsFormatter]
160
+ }
161
+ }
162
+ ];
163
+
164
+ if (ansiblePlaybook !== undefined) {
165
+ initialState.ansiblePlaybook = transformAnsiblePlaybook(ansiblePlaybook);
166
+ }
167
+ initialState.services = services;
168
+ initialState.ansibleVarsAll = ansibleVarsAll;
169
+
170
+ dispatch({
171
+ type: APPLICATION_DEFINITION_INIT,
172
+ payload: initialState,
173
+ });
174
+ };
175
+
176
+ const errorHandler = (msg, err) => {
177
+ const error = {
178
+ errorMsg: 'Failed to fetch data from server.',
179
+ statusText: err,
180
+ };
181
+ return { type: msg, payload: { error } };
182
+ };
183
+
184
+ export const loadAnsibleData = (
185
+ ansiblePlaybookId,
186
+ additionalData
187
+ ) => dispatch => {
188
+ dispatch({ type: APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST });
189
+
190
+ const baseUrl = additionalData.url;
191
+ const realUrl = baseUrl.replace("__id__", ansiblePlaybookId);
192
+
193
+ return api
194
+ .get(realUrl, {}, {})
195
+ .then(({ data }) =>
196
+ dispatch({
197
+ type: APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS,
198
+ payload: { ...data }
199
+ })
200
+ )
201
+ .catch(error => dispatch(errorHandler(APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE, error)));
202
+ };
203
+
204
+ export const addApplicationDefinitionService = (additionalData) => ({
205
+ type: APPLICATION_DEFINITION_SERVICE_ADD,
206
+ payload: {
207
+ ...additionalData,
208
+ },
209
+ });
210
+
211
+ export const deleteApplicationDefinitionService = (additionalData) => ({
212
+ type: APPLICATION_DEFINITION_SERVICE_DELETE,
213
+ payload: {
214
+ ...additionalData,
215
+ },
216
+ });
217
+
218
+ export const activateEditApplicationDefinitionService = (additionalData) => ({
219
+ type: APPLICATION_DEFINITION_SERVICE_EDIT_ACTIVATE,
220
+ payload: {
221
+ ...additionalData,
222
+ },
223
+ });
224
+
225
+ export const confirmEditApplicationDefinitionService = (rowData) => ({
226
+ type: APPLICATION_DEFINITION_SERVICE_EDIT_CONFIRM,
227
+ payload: {
228
+ ...rowData,
229
+ },
230
+ });
231
+
232
+ export const cancelEditApplicationDefinitionService = (rowData) => ({
233
+ type: APPLICATION_DEFINITION_SERVICE_EDIT_CANCEL,
234
+ payload: {
235
+ ...rowData,
236
+ },
237
+ });
238
+
239
+ export const changeEditApplicationDefinitionService = (value, additionalData) => ({
240
+ type: APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE,
241
+ payload: {
242
+ value,
243
+ ...additionalData,
244
+ },
245
+ });
246
+
247
+ export const openForemanParameterSelectionModal = (additionalData) => dispatch => {
248
+ dispatch({
249
+ type: APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
250
+ payload: {
251
+ ...additionalData,
252
+ }
253
+ });
254
+ dispatch(
255
+ setModalOpen({ id: 'AppDefinitionForemanParamSelection' })
256
+ );
257
+ }
258
+
259
+ export const closeForemanParameterSelectionModal = (additionalData) => dispatch => {
260
+ dispatch({
261
+ type: APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
262
+ payload: {
263
+ ...additionalData,
264
+ }
265
+ });
266
+
267
+ dispatch(
268
+ setModalClosed({ id: 'AppDefinitionForemanParamSelection' })
269
+ );
270
+ }
271
+
272
+ export const openAnsibleParameterSelectionModal = (additionalData) => dispatch => {
273
+ dispatch({
274
+ type: APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
275
+ payload: {
276
+ ...additionalData,
277
+ }
278
+ });
279
+ dispatch(
280
+ setModalOpen({ id: 'AppDefinitionAnsibleParamSelection' })
281
+ );
282
+ }
283
+
284
+ export const closeAnsibleParameterSelectionModal = (additionalData) => dispatch => {
285
+ dispatch({
286
+ type: APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
287
+ payload: {
288
+ ...additionalData,
289
+ }
290
+ });
291
+
292
+ dispatch(
293
+ setModalClosed({ id: 'AppDefinitionAnsibleParamSelection' })
294
+ );
295
+ }