foreman_acd 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,9 +1,14 @@
1
1
  export const APPLICATION_DEFINITION_INIT = 'INIT_APPLICATION_DEFINITION_INIT';
2
+ export const APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST = 'APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST';
3
+ export const APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS = 'APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS';
4
+ export const APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE = 'APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE';
2
5
  export const APPLICATION_DEFINITION_SERVICE_DELETE = 'APPLICATION_DEFINITION_SERVICE_DELETE';
3
6
  export const APPLICATION_DEFINITION_SERVICE_ADD = 'APPLICATION_DEFINITION_SERVICE_ADD';
4
7
  export const APPLICATION_DEFINITION_SERVICE_EDIT_ACTIVATE = 'APPLICATION_DEFINITION_SERVICE_EDIT_ACTIVATE';
5
8
  export const APPLICATION_DEFINITION_SERVICE_EDIT_CONFIRM = 'APPLICATION_DEFINITION_SERVICE_EDIT_CONFIRM';
6
9
  export const APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE = 'APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE';
7
10
  export const APPLICATION_DEFINITION_SERVICE_EDIT_CANCEL = 'APPLICATION_DEFINITION_SERVICE_EDIT_CANCEL';
8
- export const APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_OPEN = 'APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_OPEN';
9
- export const APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_CLOSE = 'APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_CLOSE';
11
+ export const APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN = 'APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN';
12
+ export const APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE = 'APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE';
13
+ export const APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN = 'APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN';
14
+ export const APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE = 'APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE';
@@ -0,0 +1,26 @@
1
+ export function transformAnsiblePlaybook(playbook) {
2
+
3
+ const ansiblePlaybook = new Object;
4
+ ansiblePlaybook.id = playbook.id;
5
+ ansiblePlaybook.name = playbook.name;
6
+ ansiblePlaybook.groups = {};
7
+
8
+ if (playbook.hasOwnProperty('groups')) {
9
+ Object.entries(playbook.groups).forEach(([group_name,group_vars]) => {
10
+ ansiblePlaybook.groups[group_name] = [];
11
+
12
+ let id=0;
13
+ Object.entries(group_vars).forEach(([var_name,var_value]) => {
14
+ let entry = {
15
+ id: id,
16
+ name: var_name,
17
+ value: var_value
18
+ }
19
+ ansiblePlaybook.groups[group_name].push(entry);
20
+ id += 1;
21
+ });
22
+ });
23
+ }
24
+
25
+ return ansiblePlaybook;
26
+ }
@@ -8,16 +8,30 @@ import {
8
8
 
9
9
  import {
10
10
  APPLICATION_DEFINITION_INIT,
11
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST,
12
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS,
13
+ APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE,
11
14
  APPLICATION_DEFINITION_SERVICE_DELETE,
12
15
  APPLICATION_DEFINITION_SERVICE_ADD,
13
16
  APPLICATION_DEFINITION_SERVICE_EDIT_ACTIVATE,
14
17
  APPLICATION_DEFINITION_SERVICE_EDIT_CONFIRM,
15
18
  APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE,
16
19
  APPLICATION_DEFINITION_SERVICE_EDIT_CANCEL,
17
- APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_OPEN,
18
- APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_CLOSE,
20
+ APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN,
21
+ APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE,
22
+ APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN,
23
+ APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE,
19
24
  } from './ApplicationDefinitionConstants';
20
25
 
26
+ import {
27
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
28
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
29
+ } from '../ParameterSelection/ParameterSelectionConstants';
30
+
31
+ import {
32
+ transformAnsiblePlaybook,
33
+ } from './ApplicationDefinitionHelper';
34
+
21
35
  export const initialState = Immutable({
22
36
  name: false,
23
37
  error: { errorMsg: '', status: '', statusText: '' },
@@ -30,6 +44,30 @@ const applicationDefinitionConf = (state = initialState, action) => {
30
44
  case APPLICATION_DEFINITION_INIT: {
31
45
  return state.merge(payload);
32
46
  }
47
+
48
+ case APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_FAILURE: {
49
+ return state.merge({ error: payload.error, loading: false });
50
+ }
51
+ case APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_REQUEST: {
52
+ return state.set('loading', true);
53
+ }
54
+ case APPLICATION_DEFINITION_LOAD_ANSIBLE_DATA_SUCCESS: {
55
+ let newState = {};
56
+ let allVars = [];
57
+
58
+ const ansiblePlaybook = transformAnsiblePlaybook(payload);
59
+
60
+ if (ansiblePlaybook.hasOwnProperty('groups')) {
61
+ allVars = ansiblePlaybook.groups['all']
62
+ }
63
+
64
+ newState = {
65
+ ansiblePlaybook: ansiblePlaybook,
66
+ ansibleVarsAll: allVars
67
+ }
68
+
69
+ return state.merge(newState);
70
+ }
33
71
  case APPLICATION_DEFINITION_SERVICE_ADD: {
34
72
  let services = [];
35
73
  let index = 1;
@@ -39,7 +77,9 @@ const applicationDefinitionConf = (state = initialState, action) => {
39
77
  index = Math.max(...services.map(e => e.id)) + 1;
40
78
  }
41
79
 
42
- const newRow = {id: index, name: "", description: '', hostgroup: '', minCount: '', maxCount: '', parameters: [], newEntry: true };
80
+ const newRow = { id: index, name: "", description: '', hostgroup: '',
81
+ ansibleGroup: '', minCount: '', maxCount: '',
82
+ foremanParameters: [], ansibleParameters: [], newEntry: true };
43
83
  newRow.backup = cloneDeep(newRow)
44
84
  services.push(newRow);
45
85
 
@@ -72,9 +112,16 @@ const applicationDefinitionConf = (state = initialState, action) => {
72
112
  delete services[index].backup;
73
113
  delete services[index].newEntry;
74
114
 
115
+ let ansibleParameters = [];
116
+ const selectedGroup = services[index].ansibleGroup;
117
+
118
+ if (selectedGroup) {
119
+ services[index].ansibleParameters = state.ansiblePlaybook.groups[selectedGroup];
120
+ }
121
+
75
122
  return state.merge({
76
123
  editMode: false,
77
- services: services
124
+ services: services,
78
125
  });
79
126
  }
80
127
  case APPLICATION_DEFINITION_SERVICE_EDIT_CHANGE: {
@@ -101,33 +148,31 @@ const applicationDefinitionConf = (state = initialState, action) => {
101
148
  services: services
102
149
  });
103
150
  }
104
- case APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_OPEN: {
151
+ case APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_OPEN: {
105
152
  let parametersData = {};
106
153
 
107
- if (payload && payload.rowData) {
108
- parametersData.serviceDefinition = {
109
- id: payload.rowData.id,
110
- name: payload.rowData.name,
111
- hostgroup_id: payload.rowData.hostgroup
112
- }
113
- parametersData.parameters = payload.rowData.parameters;
114
-
115
- if (parametersData.parameters.length > 0) {
116
- parametersData.mode = 'editDefinition';
117
- } else {
118
- parametersData.mode = 'newDefinition';
119
- }
154
+ parametersData.paramDefinition = {
155
+ id: payload.rowData.id,
156
+ name: payload.rowData.name,
157
+ dataId: payload.rowData.hostgroup
120
158
  }
121
159
 
160
+ parametersData.type = PARAMETER_SELECTION_PARAM_TYPE_FOREMAN;
161
+ parametersData.parameters = payload.rowData.foremanParameters;
162
+ parametersData.useDefaultValue = true;
163
+ parametersData.allowRowAdjustment = true;
164
+ parametersData.allowNameAdjustment = true;
165
+ parametersData.allowDescriptionAdjustment = true;
166
+
122
167
  return state.merge({
123
168
  parametersData: parametersData,
124
169
  });
125
170
  }
126
- case APPLICATION_DEFINITION_PARAMETER_SELECTION_MODAL_CLOSE: {
171
+ case APPLICATION_DEFINITION_FOREMAN_PARAMETER_SELECTION_MODAL_CLOSE: {
127
172
  if (payload.mode == 'save') {
128
173
  const services = cloneDeep(state.services);
129
- const index = findIndex(services, { id: state.parametersData.serviceDefinition.id });
130
- services[index].parameters = cloneDeep(payload.serviceParameterSelection);
174
+ const index = findIndex(services, { id: state.parametersData.paramDefinition.id });
175
+ services[index].foremanParameters = cloneDeep(payload.parameterSelection);
131
176
 
132
177
  return state.merge({
133
178
  parametersData: null,
@@ -139,6 +184,57 @@ const applicationDefinitionConf = (state = initialState, action) => {
139
184
  });
140
185
  }
141
186
  }
187
+ case APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_OPEN: {
188
+ let parametersData = {};
189
+
190
+ if ((payload.hasOwnProperty('isAllGroup')) && (payload.isAllGroup == true)) {
191
+ parametersData.parameters = state.ansibleVarsAll;
192
+ parametersData.paramDefinition = {
193
+ isAllGroup: true,
194
+ }
195
+ } else {
196
+ parametersData.parameters = payload.rowData.ansibleParameters;
197
+ parametersData.paramDefinition = {
198
+ id: payload.rowData.id,
199
+ name: payload.rowData.name,
200
+ }
201
+ }
202
+
203
+ parametersData.type = PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE;
204
+ parametersData.useDefaultValue = false;
205
+ parametersData.allowRowAdjustment = true;
206
+ parametersData.allowNameAdjustment = true;
207
+ parametersData.allowDescriptionAdjustment = true;
208
+
209
+ return state.merge({
210
+ parametersData: parametersData,
211
+ });
212
+ }
213
+ case APPLICATION_DEFINITION_ANSIBLE_PARAMETER_SELECTION_MODAL_CLOSE: {
214
+ let newState = {};
215
+ if (payload.mode == 'save') {
216
+ if ((state.parametersData.paramDefinition.hasOwnProperty('isAllGroup')) && (state.parametersData.paramDefinition.isAllGroup == true)) {
217
+ newState = {
218
+ parametersData: null,
219
+ ansibleVarsAll: cloneDeep(payload.parameterSelection),
220
+ };
221
+ } else {
222
+ const services = cloneDeep(state.services);
223
+ const index = findIndex(services, { id: state.parametersData.paramDefinition.id });
224
+ services[index].ansibleParameters = cloneDeep(payload.parameterSelection);
225
+
226
+ newState = {
227
+ parametersData: null,
228
+ services: services,
229
+ };
230
+ }
231
+ } else {
232
+ newState = {
233
+ parametersData: null,
234
+ };
235
+ }
236
+ return state.merge(newState);
237
+ }
142
238
  default:
143
239
  return state;
144
240
  }
@@ -1,6 +1,8 @@
1
1
  const applicationDefinitionConf = state => state.foremanAcd.applicationDefinitionConf;
2
2
 
3
3
  export const selectEditMode = state => applicationDefinitionConf(state).editMode;
4
+ export const selectAnsiblePlaybook = state => applicationDefinitionConf(state).ansiblePlaybook;
4
5
  export const selectServices = state => applicationDefinitionConf(state).services;
5
6
  export const selectColumns = state => applicationDefinitionConf(state).columns;
6
7
  export const selectParametersData = state => applicationDefinitionConf(state).parametersData;
8
+ export const selectAnsibleVarsAll = state => applicationDefinitionConf(state).ansibleVarsAll;
@@ -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;
@@ -7,16 +7,20 @@ import * as ApplicationDefinitionActions from './ApplicationDefinitionActions';
7
7
 
8
8
  import {
9
9
  selectEditMode,
10
+ selectAnsiblePlaybook,
10
11
  selectServices,
11
12
  selectColumns,
12
13
  selectParametersData,
14
+ selectAnsibleVarsAll,
13
15
  } from './ApplicationDefinitionSelectors';
14
16
 
15
17
  const mapStateToProps = state => ({
16
18
  editMode: selectEditMode(state),
19
+ ansiblePlaybook: selectAnsiblePlaybook(state),
17
20
  services: selectServices(state),
18
21
  columns: selectColumns(state),
19
22
  parametersData: selectParametersData(state),
23
+ ansibleVarsAll: selectAnsibleVarsAll(state),
20
24
  });
21
25
 
22
26
  const mapDispatchToProps = dispatch =>
@@ -21,6 +21,11 @@ import {
21
21
  inlineEditFormatterFactory,
22
22
  } from 'patternfly-react';
23
23
 
24
+ import {
25
+ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN,
26
+ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE,
27
+ } from '../ParameterSelection/ParameterSelectionConstants';
28
+
24
29
  class ApplicationInstance extends React.Component {
25
30
 
26
31
  constructor(props) {
@@ -69,19 +74,19 @@ class ApplicationInstance extends React.Component {
69
74
 
70
75
  componentDidMount() {
71
76
  const {
72
- data: { mode, appDefinition, hosts, loadAppDefinitionUrl },
77
+ data: { mode, appDefinition, hosts, ansibleVarsAll, appDefinitionUrl },
73
78
  initApplicationInstance,
74
79
  addApplicationInstanceHost,
75
80
  deleteApplicationInstanceHost,
76
81
  activateEditApplicationInstanceHost,
77
82
  changeEditApplicationInstanceHost,
78
- openParameterSelectionModal,
79
- closeParameterSelectionModal,
83
+ openForemanParameterSelectionModal,
84
+ openAnsibleParameterSelectionModal,
80
85
  loadApplicationDefinition,
81
86
  } = this.props;
82
87
 
83
88
  if (mode === 'editInstance') {
84
- loadApplicationDefinition(appDefinition.id, { url: loadAppDefinitionUrl });
89
+ loadApplicationDefinition(appDefinition.id, { url: appDefinitionUrl });
85
90
  }
86
91
 
87
92
  const inlineEditButtonsFormatter = inlineEditFormatterFactory({
@@ -92,13 +97,21 @@ class ApplicationInstance extends React.Component {
92
97
  bsStyle="default"
93
98
  onClick={() => activateEditApplicationInstanceHost(additionalData)}
94
99
  >
95
- <Icon type="pf" name="edit" />
100
+ <Icon type="pf" name="edit" title="edit entry" />
96
101
  </Button>
102
+ &nbsp;
97
103
  <Button
98
104
  bsStyle="default"
99
- onClick={() => openParameterSelectionModal(additionalData)}
105
+ onClick={() => openForemanParameterSelectionModal(additionalData)}
100
106
  >
101
- <Icon type="pf" name="settings" />
107
+ <Icon type="pf" name="settings" title="change parameters" />
108
+ </Button>
109
+ &nbsp;
110
+ <Button
111
+ bsStyle="default"
112
+ onClick={() => openAnsibleParameterSelectionModal(additionalData)}
113
+ >
114
+ <span title="change ansible variables">A</span>
102
115
  </Button>
103
116
  <DeleteTableEntry
104
117
  hidden={false}
@@ -113,9 +126,14 @@ class ApplicationInstance extends React.Component {
113
126
  <Button bsStyle="default" disabled>
114
127
  <Icon type="pf" name="edit" />
115
128
  </Button>
129
+ &nbsp;
116
130
  <Button bsStyle="default" disabled>
117
131
  <Icon type="pf" name="settings" />
118
132
  </Button>
133
+ &nbsp;
134
+ <Button bsStyle="default" disabled>
135
+ <span>A</span>
136
+ </Button>
119
137
  <DeleteTableEntry
120
138
  hidden={false}
121
139
  disabled={true}
@@ -188,6 +206,7 @@ class ApplicationInstance extends React.Component {
188
206
  initApplicationInstance(
189
207
  appDefinition,
190
208
  hosts,
209
+ ansibleVarsAll,
191
210
  this.headerFormatter,
192
211
  this.inlineEditFormatter,
193
212
  this.inlineEditButtonsFormatter,
@@ -196,7 +215,7 @@ class ApplicationInstance extends React.Component {
196
215
 
197
216
  render() {
198
217
  const {
199
- data: { mode, applications, organization, location, loadForemanDataUrl, loadAppDefinitionUrl },
218
+ data: { mode, applications, organization, location, foremanDataUrl, appDefinitionUrl },
200
219
  appDefinition,
201
220
  services,
202
221
  hosts,
@@ -204,9 +223,9 @@ class ApplicationInstance extends React.Component {
204
223
  addApplicationInstanceHost,
205
224
  confirmEditApplicationInstanceHost,
206
225
  cancelEditApplicationInstanceHost,
207
- openParameterSelectionModal,
208
- closeParameterSelectionModal,
209
- ParameterSelectionModal,
226
+ closeForemanParameterSelectionModal,
227
+ openAnsibleParameterSelectionModal,
228
+ closeAnsibleParameterSelectionModal,
210
229
  loadApplicationDefinition,
211
230
  } = this.props;
212
231
 
@@ -232,7 +251,7 @@ class ApplicationInstance extends React.Component {
232
251
  options={ applications }
233
252
  onChange={ loadApplicationDefinition }
234
253
  selectValue={ appDefinition.id.toString() }
235
- additionalData={{url: loadAppDefinitionUrl}}
254
+ additionalData={{url: appDefinitionUrl}}
236
255
  />
237
256
  </div>
238
257
  <div className="form-group">
@@ -269,33 +288,73 @@ class ApplicationInstance extends React.Component {
269
288
  />
270
289
  </Table.PfProvider>
271
290
  <AddTableEntry
272
- hidden={ false }
273
- disabled={ this.props.editMode }
274
- onAddTableEntry={ addApplicationInstanceHost }
291
+ hidden={ false }
292
+ disabled={ this.props.editMode }
293
+ onAddTableEntry={ addApplicationInstanceHost }
275
294
  />
295
+ <span style={{ marginLeft: 30 }}>
296
+ Ansible group vars 'all':
297
+ <Button
298
+ style={{ marginLeft: 10 }}
299
+ bsStyle="default"
300
+ disabled={ this.props.editMode }
301
+ onClick={() => openAnsibleParameterSelectionModal({
302
+ isAllGroup: true
303
+ })}
304
+ >
305
+ <span title="change ansible variables for 'all'">A</span>
306
+ </Button>
307
+ </span>
276
308
  </div>
277
309
  <div>
278
310
  <ForemanModal
279
- id="AppInstanceParamSelection"
311
+ id="AppInstanceForemanParamSelection"
280
312
  dialogClassName="param_selection_modal"
281
- title="Parameter specification for Application Instance"
313
+ title="Foreman Parameter specification for Application Instance"
282
314
  >
283
315
  <ForemanModal.Header closeButton={false}>
284
316
  Parameter specification
285
317
  </ForemanModal.Header>
286
318
  {this.props.parametersData ? (
287
319
  <ParameterSelection
320
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_FOREMAN }
288
321
  location={ location }
289
322
  organization={ organization }
290
- loadForemanDataUrl= { loadForemanDataUrl }
323
+ paramDataUrl= { foremanDataUrl }
291
324
  data={ this.props.parametersData }
292
325
  />
293
326
  ) : (<span>Empty</span>)
294
327
  }
295
328
  <ForemanModal.Footer>
296
329
  <div>
297
- <Button bsStyle="primary" onClick={() => closeParameterSelectionModal({ mode: 'save' })}>Save</Button>
298
- <Button bsStyle="default" onClick={() => closeParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
330
+ <Button bsStyle="primary" onClick={() => closeForemanParameterSelectionModal({ mode: 'save' })}>Save</Button>
331
+ <Button bsStyle="default" onClick={() => closeForemanParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
332
+ </div>
333
+ </ForemanModal.Footer>
334
+ </ForemanModal>
335
+ </div>
336
+ <div>
337
+ <ForemanModal
338
+ id="AppInstanceAnsibleParamSelection"
339
+ dialogClassName="param_selection_modal"
340
+ title="Ansible group variables for Application Instance"
341
+ >
342
+ <ForemanModal.Header closeButton={false}>
343
+ Parameter specification
344
+ </ForemanModal.Header>
345
+ {this.props.parametersData ? (
346
+ <ParameterSelection
347
+ paramType={ PARAMETER_SELECTION_PARAM_TYPE_ANSIBLE }
348
+ location={ location }
349
+ organization={ organization }
350
+ data={ this.props.parametersData }
351
+ />
352
+ ) : (<span>Empty</span>)
353
+ }
354
+ <ForemanModal.Footer>
355
+ <div>
356
+ <Button bsStyle="primary" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'save' })}>Save</Button>
357
+ <Button bsStyle="default" onClick={() => closeAnsibleParameterSelectionModal({ mode: 'cancel' })}>Cancel</Button>
299
358
  </div>
300
359
  </ForemanModal.Footer>
301
360
  </ForemanModal>
@@ -306,6 +365,12 @@ class ApplicationInstance extends React.Component {
306
365
  parameter='hosts'
307
366
  value={JSON.stringify(this.props.hosts)}
308
367
  />
368
+ <RailsData
369
+ key='applications_instance'
370
+ view='app_instance'
371
+ parameter='ansible_vars_all'
372
+ value={JSON.stringify(this.props.ansibleVarsAll)}
373
+ />
309
374
  </span>
310
375
  )};
311
376
  }
@@ -316,6 +381,7 @@ ApplicationInstance.defaultProps = {
316
381
  editMode: false,
317
382
  services: [],
318
383
  hosts: [],
384
+ ansibleVarsAll: [],
319
385
  parametersData: {},
320
386
  columns: [],
321
387
  editParamsOfRowId: null,
@@ -327,6 +393,8 @@ ApplicationInstance.propTypes = {
327
393
  services: PropTypes.array,
328
394
  appDefinition: PropTypes.object,
329
395
  columns: PropTypes.array,
396
+ hosts: PropTypes.array,
397
+ ansibleVarsAll: PropTypes.array,
330
398
  loadApplicationDefinition: PropTypes.func,
331
399
  addApplicationInstanceHost: PropTypes.func,
332
400
  deleteApplicationInstanceHost: PropTypes.func,
@@ -334,8 +402,10 @@ ApplicationInstance.propTypes = {
334
402
  confirmEditApplicationInstanceHost: PropTypes.func,
335
403
  cancelEditApplicationInstanceHost: PropTypes.func,
336
404
  changeEditApplicationInstanceHost: PropTypes.func,
337
- openParameterSelectionModal: PropTypes.func,
338
- closeParameterSelectionModal: PropTypes.func,
405
+ openForemanParameterSelectionModal: PropTypes.func,
406
+ closeForemanParameterSelectionModal: PropTypes.func,
407
+ openAnsibleParameterSelectionModal: PropTypes.func,
408
+ closeAnsibleParameterSelectionModal: PropTypes.func,
339
409
  parametersData: PropTypes.object,
340
410
  };
341
411