foreman_acd 0.0.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +107 -56
  3. data/app/controllers/foreman_acd/ansible_playbooks_controller.rb +124 -0
  4. data/app/controllers/foreman_acd/api/v2/ansible_playbooks_controller.rb +72 -0
  5. data/app/controllers/foreman_acd/api/v2/app_definitions_controller.rb +2 -2
  6. data/app/controllers/foreman_acd/api/v2/app_instances_controller.rb +62 -0
  7. data/app/controllers/foreman_acd/app_definitions_controller.rb +46 -9
  8. data/app/controllers/foreman_acd/app_instances_controller.rb +96 -90
  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/foreman_acd/remote_execution_controller.rb +46 -0
  13. data/app/controllers/ui_acd_controller.rb +20 -4
  14. data/app/lib/actions/foreman_acd/deploy_all_hosts.rb +42 -0
  15. data/app/lib/actions/foreman_acd/run_configurator.rb +41 -0
  16. data/app/models/concerns/foreman_acd/host_managed_extensions.rb +51 -0
  17. data/app/models/foreman_acd/acd_provider.rb +30 -0
  18. data/app/models/foreman_acd/ansible_playbook.rb +67 -0
  19. data/app/models/foreman_acd/app_definition.rb +25 -1
  20. data/app/models/foreman_acd/app_instance.rb +42 -0
  21. data/app/models/foreman_acd/foreman_host.rb +23 -0
  22. data/app/models/foreman_acd/taxonomy_extensions.rb +17 -0
  23. data/app/services/foreman_acd/app_configurator.rb +54 -0
  24. data/app/services/foreman_acd/app_deployer.rb +151 -0
  25. data/app/services/foreman_acd/inventory_creator.rb +54 -0
  26. data/app/views/foreman_acd/ansible_playbooks/_form.html.erb +30 -0
  27. data/app/views/foreman_acd/ansible_playbooks/edit.html.erb +11 -0
  28. data/app/views/foreman_acd/ansible_playbooks/index.html.erb +30 -0
  29. data/app/views/foreman_acd/ansible_playbooks/new.html.erb +3 -0
  30. data/app/views/foreman_acd/api/v2/ansible_playbooks/base.json.rabl +5 -0
  31. data/app/views/foreman_acd/api/v2/ansible_playbooks/index.json.rabl +5 -0
  32. data/app/views/foreman_acd/api/v2/ansible_playbooks/show.json.rabl +9 -0
  33. data/app/views/foreman_acd/api/v2/app_definitions/base.json.rabl +5 -0
  34. data/app/views/foreman_acd/api/v2/app_definitions/index.json.rabl +5 -0
  35. data/app/views/foreman_acd/api/v2/app_definitions/show.json.rabl +9 -0
  36. data/app/views/foreman_acd/api/v2/app_instances/base.json.rabl +5 -0
  37. data/app/views/foreman_acd/api/v2/app_instances/index.json.rabl +5 -0
  38. data/app/views/foreman_acd/api/v2/app_instances/show.json.rabl +5 -0
  39. data/app/views/foreman_acd/app_definitions/_form.html.erb +34 -20
  40. data/app/views/foreman_acd/app_definitions/edit.html.erb +10 -0
  41. data/app/views/foreman_acd/app_definitions/import.html.erb +18 -0
  42. data/app/views/foreman_acd/app_definitions/index.html.erb +10 -6
  43. data/app/views/foreman_acd/app_instances/_form.html.erb +12 -10
  44. data/app/views/foreman_acd/app_instances/edit.html.erb +10 -0
  45. data/app/views/foreman_acd/app_instances/index.html.erb +87 -9
  46. data/app/views/foreman_acd/app_instances/report.html.erb +22 -0
  47. data/app/views/templates/job/run_acd_ansible_playbook.erb +62 -0
  48. data/app/views/ui_acd/ansible_data.json.rabl +6 -0
  49. data/app/views/ui_acd/app.json.rabl +6 -2
  50. data/app/views/ui_acd/app_definition.json.rabl +1 -1
  51. data/app/views/ui_acd/{fdata.json.rabl → foreman_data.json.rabl} +1 -1
  52. data/config/routes.rb +35 -1
  53. data/db/migrate/20190610202252_create_app_definitions.rb +1 -3
  54. data/db/migrate/20190625140305_create_app_instances.rb +1 -1
  55. data/db/migrate/20200916091018_create_ansible_playbooks.rb +20 -0
  56. data/db/migrate/20200917120220_add_ansible_playbook_id.rb +14 -0
  57. data/db/migrate/20201016002819_add_ansible_vars_all_to_app_definitions.rb +8 -0
  58. data/db/migrate/20201016104338_add_ansible_vars_all_to_app_instances.rb +8 -0
  59. data/db/migrate/20210112111548_add_organization_to_app_instance.rb +22 -0
  60. data/db/migrate/20210112113853_add_location_to_app_instance.rb +8 -0
  61. data/db/migrate/20210202141658_create_foreman_hosts.rb +24 -0
  62. data/db/migrate/20210204111306_remove_hosts_from_app_instances.rb +8 -0
  63. data/db/migrate/20210209091014_rename_acd_tables.rb +16 -0
  64. data/db/migrate/20210216083522_add_last_progress_report.rb +8 -0
  65. data/db/migrate/20210216091529_add_last_deploy_task.rb +8 -0
  66. data/db/seeds.d/62_acd_proxy_feature.rb +4 -0
  67. data/db/seeds.d/75-job_templates.rb +13 -0
  68. data/lib/foreman_acd/engine.rb +21 -3
  69. data/lib/foreman_acd/plugin.rb +112 -20
  70. data/lib/foreman_acd/version.rb +1 -1
  71. data/locale/en/foreman_acd.edit.po +326 -0
  72. data/locale/en/foreman_acd.po +232 -2
  73. data/locale/en/foreman_acd.po.time_stamp +0 -0
  74. data/locale/foreman_acd.pot +343 -8
  75. data/package.json +1 -1
  76. data/test/controllers/ansible_playbooks_controller_test.rb +27 -0
  77. data/webpack/components/ApplicationDefinition/ApplicationDefinition.js +391 -0
  78. data/webpack/components/ApplicationDefinition/ApplicationDefinition.scss +1 -0
  79. data/webpack/components/ApplicationDefinition/ApplicationDefinitionActions.js +303 -0
  80. data/webpack/components/ApplicationDefinition/ApplicationDefinitionConstants.js +15 -0
  81. data/webpack/components/ApplicationDefinition/ApplicationDefinitionHelper.js +26 -0
  82. data/webpack/components/ApplicationDefinition/ApplicationDefinitionReducer.js +269 -0
  83. data/webpack/components/ApplicationDefinition/ApplicationDefinitionSelectors.js +9 -0
  84. data/webpack/components/ApplicationDefinition/components/AnsiblePlaybookSelector.js +49 -0
  85. data/webpack/components/ApplicationDefinition/index.js +35 -0
  86. data/webpack/components/ApplicationInstance/ApplicationInstance.js +451 -0
  87. data/webpack/components/ApplicationInstance/ApplicationInstance.scss +11 -0
  88. data/webpack/components/ApplicationInstance/ApplicationInstanceActions.js +247 -0
  89. data/webpack/components/ApplicationInstance/ApplicationInstanceConstants.js +15 -0
  90. data/webpack/components/ApplicationInstance/ApplicationInstanceReducer.js +309 -0
  91. data/webpack/components/ApplicationInstance/ApplicationInstanceSelectors.js +10 -0
  92. data/webpack/components/ApplicationInstance/components/AppDefinitionSelector.js +49 -0
  93. data/webpack/components/ApplicationInstance/components/Service.js +30 -0
  94. data/webpack/components/ApplicationInstance/components/ServiceCounter.js +37 -0
  95. data/webpack/components/ApplicationInstance/index.js +37 -0
  96. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.js +148 -0
  97. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReport.scss +44 -0
  98. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportActions.js +42 -0
  99. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportConstants.js +2 -0
  100. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportReducer.js +38 -0
  101. data/webpack/components/ApplicationInstanceReport/ApplicationInstanceReportSelectors.js +4 -0
  102. data/webpack/components/ApplicationInstanceReport/components/ReportViewer.js +26 -0
  103. data/webpack/components/ApplicationInstanceReport/index.js +25 -0
  104. data/webpack/components/ParameterSelection/ParameterSelection.js +131 -192
  105. data/webpack/components/ParameterSelection/ParameterSelection.scss +9 -0
  106. data/webpack/components/ParameterSelection/ParameterSelectionActions.js +87 -110
  107. data/webpack/components/ParameterSelection/ParameterSelectionConstants.js +15 -19
  108. data/webpack/components/ParameterSelection/ParameterSelectionHelper.js +3 -35
  109. data/webpack/components/ParameterSelection/ParameterSelectionReducer.js +116 -84
  110. data/webpack/components/ParameterSelection/ParameterSelectionSelectors.js +3 -7
  111. data/webpack/components/ParameterSelection/__fixtures__/parameterSelection.fixtures.js +12 -21
  112. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionData_1.fixtures.js +1 -1
  113. data/webpack/components/ParameterSelection/__fixtures__/parameterSelectionReducer.fixtures.js +3 -45
  114. data/webpack/components/ParameterSelection/__tests__/ParameterSelection.test.js +20 -0
  115. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionReducer.test.js +22 -46
  116. data/webpack/components/ParameterSelection/__tests__/ParameterSelectionSelectors.test.js +6 -6
  117. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelection.test.js.snap +40 -265
  118. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionReducer.test.js.snap +11 -96
  119. data/webpack/components/ParameterSelection/__tests__/__snapshots__/ParameterSelectionSelectors.test.js.snap +3 -9
  120. data/webpack/components/ParameterSelection/index.js +6 -8
  121. data/webpack/components/common/AddTableEntry.js +30 -0
  122. data/webpack/components/common/DeleteTableEntry.js +39 -0
  123. data/webpack/components/common/EasyHeaderFormatter.js +18 -0
  124. data/webpack/components/common/EditTableEntry.js +50 -0
  125. data/webpack/components/common/ExtSelect.js +43 -0
  126. data/webpack/components/common/LockTableEntry.js +60 -0
  127. data/webpack/components/common/RailsData.js +27 -0
  128. data/webpack/components/common/__tests__/AddTableEntry.test.js +26 -0
  129. data/webpack/components/common/__tests__/DeleteTableEntry.test.js +29 -0
  130. data/webpack/components/common/__tests__/ExtSelect.test.js +38 -0
  131. data/webpack/components/common/__tests__/RailsData.test.js +16 -0
  132. data/webpack/components/common/__tests__/__snapshots__/AddParameter.test.js.snap +35 -0
  133. data/webpack/components/common/__tests__/__snapshots__/AddTableEntry.test.js.snap +35 -0
  134. data/webpack/components/common/__tests__/__snapshots__/DeleteParameter.test.js.snap +41 -0
  135. data/webpack/components/common/__tests__/__snapshots__/DeleteTableEntry.test.js.snap +41 -0
  136. data/webpack/components/common/__tests__/__snapshots__/ExtSelect.test.js.snap +18 -0
  137. data/webpack/components/common/__tests__/__snapshots__/RailsData.test.js.snap +10 -0
  138. data/webpack/helper.js +20 -0
  139. data/webpack/index.js +6 -0
  140. data/webpack/reducer.js +43 -3
  141. metadata +114 -20
@@ -0,0 +1,9 @@
1
+ const applicationDefinitionConf = state => state.foremanAcd.applicationDefinitionConf;
2
+
3
+ export const selectEditMode = state => applicationDefinitionConf(state).editMode;
4
+ export const selectAnsiblePlaybook = state => applicationDefinitionConf(state).ansiblePlaybook;
5
+ export const selectServices = state => applicationDefinitionConf(state).services;
6
+ export const selectColumns = state => applicationDefinitionConf(state).columns;
7
+ export const selectParametersData = state => applicationDefinitionConf(state).parametersData;
8
+ export const selectAnsibleVarsAll = state => applicationDefinitionConf(state).ansibleVarsAll;
9
+ export const selectParamEditMode = state => applicationDefinitionConf(state).paramEditMode;
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import ExtSelect from '../../common/ExtSelect';
4
+ import RailsData from '../../common/RailsData'
5
+
6
+ const AnsiblePlaybookSelector= ({
7
+ label,
8
+ hidden,
9
+ editable,
10
+ viewText,
11
+ selectValue,
12
+ onChange,
13
+ options,
14
+ additionalData,
15
+ }) =>{
16
+ return (
17
+ <div className="form-group">
18
+ <label className="col-md-2 control-label">{label}</label>
19
+ <div className="col-md-4">
20
+ <ExtSelect
21
+ editable={editable}
22
+ viewText={viewText}
23
+ selectValue={selectValue}
24
+ onChange={onChange}
25
+ options={options}
26
+ additionalData={additionalData}
27
+ />
28
+ <RailsData
29
+ key='ansible_playbook_id'
30
+ view='app_definition'
31
+ parameter='acd_ansible_playbook_id'
32
+ value={selectValue}
33
+ />
34
+ </div>
35
+ </div>
36
+ );
37
+ };
38
+
39
+ AnsiblePlaybookSelector.propTypes = {
40
+ label: PropTypes.string.isRequired,
41
+ editable: PropTypes.bool.isRequired,
42
+ viewText: PropTypes.string,
43
+ selectValue: PropTypes.string,
44
+ onChange: PropTypes.func.isRequired,
45
+ options: PropTypes.object,
46
+ additionalData: PropTypes.object,
47
+ };
48
+
49
+ export default AnsiblePlaybookSelector;
@@ -0,0 +1,35 @@
1
+ import { bindActionCreators } from 'redux';
2
+ import { connect } from 'react-redux';
3
+
4
+ import './ApplicationDefinition.scss';
5
+ import ApplicationDefinition from './ApplicationDefinition';
6
+ import * as ApplicationDefinitionActions from './ApplicationDefinitionActions';
7
+
8
+ import {
9
+ selectEditMode,
10
+ selectAnsiblePlaybook,
11
+ selectServices,
12
+ selectColumns,
13
+ selectParametersData,
14
+ selectAnsibleVarsAll,
15
+ selectParamEditMode,
16
+ } from './ApplicationDefinitionSelectors';
17
+
18
+ const mapStateToProps = state => ({
19
+ editMode: selectEditMode(state),
20
+ ansiblePlaybook: selectAnsiblePlaybook(state),
21
+ services: selectServices(state),
22
+ columns: selectColumns(state),
23
+ parametersData: selectParametersData(state),
24
+ ansibleVarsAll: selectAnsibleVarsAll(state),
25
+ paramEditMode: selectParamEditMode(state),
26
+ });
27
+
28
+ const mapDispatchToProps = dispatch =>
29
+ bindActionCreators(ApplicationDefinitionActions, dispatch);
30
+
31
+ export default connect(
32
+ mapStateToProps,
33
+ mapDispatchToProps
34
+ )(ApplicationDefinition);
35
+
@@ -0,0 +1,451 @@
1
+ import React, { useState } from 'react'
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ Icon,
5
+ Button,
6
+ } from 'patternfly-react';
7
+ import * as resolve from 'table-resolver';
8
+ import ForemanModal from 'foremanReact/components/ForemanModal';
9
+ import {
10
+ sprintf,
11
+ translate as __
12
+ } from 'foremanReact/common/I18n';
13
+ import Select from 'foremanReact/components/common/forms/Select';
14
+ import ParameterSelection from '../ParameterSelection';
15
+ import AddTableEntry from '../common/AddTableEntry';
16
+ import DeleteTableEntry from '../common/DeleteTableEntry';
17
+ import RailsData from '../common/RailsData';
18
+ import EasyHeaderFormatter from '../common/EasyHeaderFormatter';
19
+ import AppDefinitionSelector from './components/AppDefinitionSelector';
20
+ import ServiceCounter from './components/ServiceCounter';
21
+ import { arrayToObject } from '../../helper';
22
+
23
+ import {
24
+ Table,
25
+ FormControl,
26
+ inlineEditFormatterFactory,
27
+ } from 'patternfly-react';
28
+
29
+ import {
30
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
31
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
32
+ } from '../ParameterSelection/ParameterSelectionConstants';
33
+
34
+ class ApplicationInstance extends React.Component {
35
+
36
+ constructor(props) {
37
+ super(props);
38
+ }
39
+
40
+ isEditing({rowData}) {
41
+ return (rowData.backup !== undefined);
42
+ }
43
+
44
+ addTableEntryAllowed() {
45
+ return this.props.editMode || this.props.appDefinition.id == ''
46
+ }
47
+
48
+ validateParameters() {
49
+ let result = true;
50
+ let msg = "";
51
+
52
+ this.props.hosts.forEach(h => {
53
+ if (h.foremanParameters.map(e => e.value).filter(i => i == "").length > 0) {
54
+ result = false;
55
+
56
+ if (msg == "") {
57
+ msg += __("For some hosts the values for some parameters are missing. Check the values for these hosts:\n");
58
+ }
59
+ msg += "- "+ h.hostname +"\n";
60
+ }
61
+ });
62
+
63
+ const invalidMinServices = this.props.services.filter(s => (Number(s.minCount) != 0) && (s.currentCount < s.minCount));
64
+ const invalidMaxServices = this.props.services.filter(s => (Number(s.maxCount) != 0) && (s.currentCount > s.maxCount));
65
+
66
+ console.log(invalidMinServices);
67
+
68
+ if (invalidMinServices.length > 0 || invalidMaxServices.length > 0) {
69
+ result = false;
70
+
71
+ if (msg != "") {
72
+ msg += "\n";
73
+ }
74
+
75
+ msg += __("Unachieved service counts:");
76
+ msg += "\n";
77
+
78
+ invalidMinServices.map(s => { msg += sprintf(
79
+ __(`- service ${s.name} expects at ${s.minCount} least configured hosts\n`)
80
+ )});
81
+
82
+ invalidMaxServices.map(s => { msg += sprintf(
83
+ __(`- service ${s.name} expects no more than ${s.axCount} configured hosts\n`)
84
+ )});
85
+ }
86
+
87
+ return {
88
+ validateResult: result,
89
+ validateMsg: msg
90
+ }
91
+ }
92
+
93
+ componentDidMount() {
94
+ const {
95
+ data: { mode, appDefinition, hosts, ansibleVarsAll, appDefinitionUrl },
96
+ initApplicationInstance,
97
+ addApplicationInstanceHost,
98
+ deleteApplicationInstanceHost,
99
+ activateEditApplicationInstanceHost,
100
+ changeEditApplicationInstanceHost,
101
+ openForemanParameterSelectionModal,
102
+ openAnsibleParameterSelectionModal,
103
+ loadApplicationDefinition,
104
+ } = this.props;
105
+
106
+ if (mode === 'editInstance') {
107
+ loadApplicationDefinition(appDefinition.id, { url: appDefinitionUrl });
108
+ }
109
+
110
+ const inlineEditButtonsFormatter = inlineEditFormatterFactory({
111
+ isEditing: additionalData => this.props.editMode,
112
+ renderValue: (value, additionalData) => (
113
+ <td style={{ padding: '2px' }}>
114
+ <Button
115
+ bsStyle="default"
116
+ onClick={() => activateEditApplicationInstanceHost(additionalData)}
117
+ >
118
+ <Icon type="pf" name="edit" title={__("edit entry")} />
119
+ </Button>
120
+ &nbsp;
121
+ <Button
122
+ bsStyle="default"
123
+ onClick={() => openForemanParameterSelectionModal(additionalData)}
124
+ >
125
+ <Icon type="pf" name="settings" title={__("change parameters")} />
126
+ </Button>
127
+ &nbsp;
128
+ <Button
129
+ bsStyle="default"
130
+ onClick={() => openAnsibleParameterSelectionModal(additionalData)}
131
+ >
132
+ <span title={__("change ansible variables")}>A</span>
133
+ </Button>
134
+ &nbsp;
135
+ <DeleteTableEntry
136
+ hidden={false}
137
+ disabled={false}
138
+ onDeleteTableEntry={deleteApplicationInstanceHost}
139
+ additionalData={additionalData}
140
+ />
141
+ </td>
142
+ ),
143
+ renderEdit: (value, additionalData) => (
144
+ <td style={{ padding: '2px' }}>
145
+ <Button bsStyle="default" disabled>
146
+ <Icon type="pf" name={__("edit")} />
147
+ </Button>
148
+ &nbsp;
149
+ <Button bsStyle="default" disabled>
150
+ <Icon type="pf" name={__("settings")} />
151
+ </Button>
152
+ &nbsp;
153
+ <Button bsStyle="default" disabled>
154
+ <span>A</span>
155
+ </Button>
156
+ &nbsp;
157
+ <DeleteTableEntry
158
+ hidden={false}
159
+ disabled={true}
160
+ onDeleteTableEntry={deleteApplicationInstanceHost}
161
+ additionalData={additionalData}
162
+ />
163
+ </td>
164
+ )
165
+ });
166
+ this.inlineEditButtonsFormatter = inlineEditButtonsFormatter;
167
+
168
+ this.headerFormatter = EasyHeaderFormatter;
169
+
170
+ const inlineEditFormatterImpl = {
171
+ renderValue: (value, additionalData) => (
172
+ <td>
173
+ <span className="static">{value}</span>
174
+ </td>
175
+ ),
176
+ renderEditText: (value, additionalData, subtype='text') => (
177
+ <td className="editing">
178
+ <FormControl
179
+ type={subtype}
180
+ defaultValue={value}
181
+ onBlur={e => changeEditApplicationInstanceHost(e.target.value, additionalData) }
182
+ />
183
+ </td>
184
+ ),
185
+ renderEditSelect: (value, additionalData, options) => (
186
+ <td className="editing">
187
+ <Select
188
+ value={value.toString()}
189
+ onChange={e => changeEditApplicationInstanceHost(e.target.value, additionalData) }
190
+ options={options}
191
+ allowClear
192
+ key="key"
193
+ />
194
+ </td>
195
+ )
196
+ };
197
+
198
+ const inlineEditFormatter = inlineEditFormatterFactory({
199
+ isEditing: additionalData => this.isEditing(additionalData),
200
+ renderValue: (value, additionalData) => {
201
+ let prettyValue = value;
202
+ if (additionalData.property == 'service') {
203
+ const serviceList = arrayToObject(this.props.services, "id", "name");
204
+ prettyValue = serviceList[value];
205
+ }
206
+ return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
207
+ },
208
+ renderEdit: (value, additionalData) => {
209
+ let prettyValue = value;
210
+ if (additionalData.property == 'service') {
211
+ const availableServices = this.props.services.filter(service => ((Number(service['maxCount']) == 0) || (service['currentCount'] < service['maxCount'])));
212
+ const serviceList = arrayToObject(availableServices, "id", "name");
213
+
214
+ if (additionalData.rowData.newEntry === true) {
215
+ return inlineEditFormatterImpl.renderEditSelect(value, additionalData, serviceList);
216
+ }
217
+ prettyValue = serviceList[value];
218
+ return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
219
+ }
220
+ if (additionalData.property == 'hostname') {
221
+ if (additionalData.rowData.newEntry === true) {
222
+ return inlineEditFormatterImpl.renderEditText(value, additionalData);
223
+ }
224
+ return inlineEditFormatterImpl.renderValue(prettyValue, additionalData)
225
+ }
226
+ return inlineEditFormatterImpl.renderEditText(prettyValue, additionalData);
227
+ }
228
+ });
229
+ this.inlineEditFormatter = inlineEditFormatter;
230
+
231
+ initApplicationInstance(
232
+ appDefinition,
233
+ hosts,
234
+ ansibleVarsAll,
235
+ this.headerFormatter,
236
+ this.inlineEditFormatter,
237
+ this.inlineEditButtonsFormatter,
238
+ );
239
+ };
240
+
241
+ render() {
242
+ const {
243
+ data: { mode, applications, organization, location, foremanDataUrl, appDefinitionUrl },
244
+ appDefinition,
245
+ services,
246
+ hosts,
247
+ columns,
248
+ addApplicationInstanceHost,
249
+ confirmEditApplicationInstanceHost,
250
+ cancelEditApplicationInstanceHost,
251
+ closeForemanParameterSelectionModal,
252
+ openAnsibleParameterSelectionModal,
253
+ closeAnsibleParameterSelectionModal,
254
+ changeParameterSelectionMode,
255
+ loadApplicationDefinition,
256
+ } = this.props;
257
+
258
+ let { validateResult, validateMsg } = this.validateParameters();
259
+
260
+ if (validateResult == false) {
261
+ $('input[type="submit"][name="commit"]').attr("disabled", true);
262
+ } else {
263
+ $('input[type="submit"][name="commit"]').attr("disabled", false);
264
+ }
265
+
266
+ return (
267
+ <span>
268
+ <div class="service-counter">
269
+ <ServiceCounter
270
+ title="Service counts"
271
+ serviceList={ services }
272
+ hostList={ hosts }
273
+ />
274
+ </div>
275
+ <div>
276
+ <AppDefinitionSelector
277
+ label="Application Definition"
278
+ editable={ mode == 'newInstance' }
279
+ viewText={ appDefinition.name }
280
+ options={ applications }
281
+ onChange={ loadApplicationDefinition }
282
+ selectValue={ appDefinition.id.toString() }
283
+ additionalData={{url: appDefinitionUrl}}
284
+ />
285
+ {appDefinition.id == '' ? (
286
+ <p style={{ paddingTop: 25 }}>
287
+ <pre>{ "App Definition can't be blank" }</pre>
288
+ </p>
289
+ ) : (<div></div>)}
290
+ </div>
291
+ <div className="form-group">
292
+ <Table.PfProvider
293
+ striped
294
+ bordered
295
+ hover
296
+ dataTable
297
+ inlineEdit
298
+ columns={columns}
299
+ components={{
300
+ body: {
301
+ row: Table.InlineEditRow,
302
+ cell: cellProps => cellProps.children
303
+ }
304
+ }}
305
+ >
306
+ <Table.Header headerRows={resolve.headerRows({ columns })} />
307
+ <Table.Body
308
+ rows={hosts}
309
+ rowKey="id"
310
+ onRow={(rowData, { rowIndex }) => ({
311
+ role: 'row',
312
+ isEditing: () => this.isEditing({ rowData }),
313
+ onCancel: () => cancelEditApplicationInstanceHost({ rowData, rowIndex }),
314
+ onConfirm: () => confirmEditApplicationInstanceHost({ rowData, rowIndex }),
315
+ last: rowIndex === services.length - 1
316
+ })}
317
+ />
318
+ </Table.PfProvider>
319
+ <AddTableEntry
320
+ hidden={ false }
321
+ disabled={ this.addTableEntryAllowed() }
322
+ onAddTableEntry={ addApplicationInstanceHost }
323
+ />
324
+ <span style={{ marginLeft: 30 }}>
325
+ Ansible group vars 'all':
326
+ <Button
327
+ style={{ marginLeft: 10 }}
328
+ bsStyle="default"
329
+ disabled={ this.props.editMode }
330
+ onClick={() => openAnsibleParameterSelectionModal({
331
+ isAllGroup: true
332
+ })}
333
+ >
334
+ <span title={__("change ansible variables for 'all'")}>A</span>
335
+ </Button>
336
+ </span>
337
+ </div>
338
+ <div>
339
+ <ForemanModal
340
+ id="AppInstanceForemanParamSelection"
341
+ dialogClassName="param_selection_modal"
342
+ title={__("Foreman Parameter specification for Application Instance")}
343
+ >
344
+ <ForemanModal.Header closeButton={false}>
345
+ Parameter specification
346
+ </ForemanModal.Header>
347
+ {this.props.parametersData ? (
348
+ <ParameterSelection
349
+ editModeCallback={ (hide) => changeParameterSelectionMode({ mode: hide })}
350
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN }
351
+ location={ location }
352
+ organization={ organization }
353
+ paramDataUrl= { foremanDataUrl }
354
+ data={ this.props.parametersData }
355
+ />
356
+ ) : (<span>Empty</span>)
357
+ }
358
+ <ForemanModal.Footer>
359
+ <div>
360
+ <Button bsStyle="primary" disabled={this.props.paramEditMode} onClick={() => closeForemanParameterSelectionModal({ mode: 'save' })}>{__("Save")}</Button>
361
+ <Button bsStyle="default" disabled={this.props.paramEditMode} onClick={() => closeForemanParameterSelectionModal({ mode: 'cancel' })}>{__("Cancel")}</Button>
362
+ </div>
363
+ </ForemanModal.Footer>
364
+ </ForemanModal>
365
+ </div>
366
+ <div>
367
+ <ForemanModal
368
+ id="AppInstanceAnsibleParamSelection"
369
+ dialogClassName="param_selection_modal"
370
+ title={__("Ansible group variables for Application Instance")}
371
+ >
372
+ <ForemanModal.Header closeButton={false}>
373
+ Parameter specification
374
+ </ForemanModal.Header>
375
+ {this.props.parametersData ? (
376
+ <ParameterSelection
377
+ editModeCallback={ (hide) => changeParameterSelectionMode({ mode: hide })}
378
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE }
379
+ location={ location }
380
+ organization={ organization }
381
+ data={ this.props.parametersData }
382
+ />
383
+ ) : (<span>Empty</span>)
384
+ }
385
+ <ForemanModal.Footer>
386
+ <div>
387
+ <Button bsStyle="primary" disabled={this.props.paramEditMode} onClick={() => closeAnsibleParameterSelectionModal({ mode: 'save' })}>{__("Save")}</Button>
388
+ <Button bsStyle="default" disabled={this.props.paramEditMode} onClick={() => closeAnsibleParameterSelectionModal({ mode: 'cancel' })}>{__("Cancel")}</Button>
389
+ </div>
390
+ </ForemanModal.Footer>
391
+ </ForemanModal>
392
+ </div>
393
+ {validateResult == false ? (
394
+ <p style={{ paddingTop: 25 }}>
395
+ <pre>{ validateMsg }</pre>
396
+ </p>
397
+ ) : (<div></div>)}
398
+ <RailsData
399
+ key='applications_instance'
400
+ view='app_instance'
401
+ parameter='hosts'
402
+ value={JSON.stringify(this.props.hosts)}
403
+ />
404
+ <RailsData
405
+ key='applications_instance'
406
+ view='app_instance'
407
+ parameter='ansible_vars_all'
408
+ value={JSON.stringify(this.props.ansibleVarsAll)}
409
+ />
410
+ </span>
411
+ )};
412
+ }
413
+
414
+ ApplicationInstance.defaultProps = {
415
+ error: {},
416
+ appDefinition: { "id": '', "name": '' },
417
+ editMode: false,
418
+ services: [],
419
+ hosts: [],
420
+ ansibleVarsAll: [],
421
+ parametersData: {},
422
+ columns: [],
423
+ editParamsOfRowId: null,
424
+ paramEditMode: false,
425
+ }
426
+
427
+ ApplicationInstance.propTypes = {
428
+ initApplicationInstance: PropTypes.func,
429
+ editMode: PropTypes.bool.isRequired,
430
+ services: PropTypes.array,
431
+ appDefinition: PropTypes.object,
432
+ columns: PropTypes.array,
433
+ hosts: PropTypes.array,
434
+ ansibleVarsAll: PropTypes.array,
435
+ loadApplicationDefinition: PropTypes.func,
436
+ addApplicationInstanceHost: PropTypes.func,
437
+ deleteApplicationInstanceHost: PropTypes.func,
438
+ activateEditApplicationInstanceHost: PropTypes.func,
439
+ confirmEditApplicationInstanceHost: PropTypes.func,
440
+ cancelEditApplicationInstanceHost: PropTypes.func,
441
+ changeEditApplicationInstanceHost: PropTypes.func,
442
+ openForemanParameterSelectionModal: PropTypes.func,
443
+ closeForemanParameterSelectionModal: PropTypes.func,
444
+ openAnsibleParameterSelectionModal: PropTypes.func,
445
+ closeAnsibleParameterSelectionModal: PropTypes.func,
446
+ changeParameterSelectionMode: PropTypes.func,
447
+ parametersData: PropTypes.object,
448
+ paramEditMode: PropTypes.bool,
449
+ };
450
+
451
+ export default ApplicationInstance;