foreman_templates 9.0.2 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/services/foreman_templates/template_exporter.rb +1 -1
- data/app/services/foreman_templates/template_importer.rb +1 -1
- data/app/views/ui_template_syncs/template_attrs.json.rabl +1 -1
- data/lib/foreman_templates/engine.rb +5 -5
- data/lib/foreman_templates/version.rb +1 -1
- data/lib/tasks/foreman_templates_tasks.rake +10 -9
- data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +2 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js +95 -140
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormHelpers.js +43 -0
- data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/index.js +0 -4
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3b520577905d85f390af67f22635c98defb339c3177cfc9b7ecfb8039b3999c2
|
|
4
|
+
data.tar.gz: ae67963f134f9b53fe2f4520c028cd8426474e3aa10dc01733a292bbf1bb8284
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 763f1cd44a8a5a91bad924c0c6eb50950b7cd552b762bc767c188eeae9f78d66ecb9f4f15d81012092683a2fff263c19bf2230e622167ec235557fac64244ea7
|
|
7
|
+
data.tar.gz: e48d8b9ac3b46195afec1d2913a4ad4a6558dc2a7ea2d325e8f6566b7697ca8780e450ced74b7604d709940660dbdd54a438c6590b4c08fd66b7fa3bdd189f88
|
|
@@ -94,7 +94,7 @@ module ForemanTemplates
|
|
|
94
94
|
def templates_to_dump
|
|
95
95
|
find_templates.each do |template|
|
|
96
96
|
if filter.present?
|
|
97
|
-
exportable =
|
|
97
|
+
exportable = /#{filter}/i.match?(template.name) ? !negate : negate
|
|
98
98
|
result = ExportResult.new(template, exportable)
|
|
99
99
|
next @result_lines << result.matching_filter unless exportable
|
|
100
100
|
|
|
@@ -70,7 +70,7 @@ module ForemanTemplates
|
|
|
70
70
|
@result_lines << parse_result.check_for_errors
|
|
71
71
|
rescue NameError => e
|
|
72
72
|
@result_lines << parse_result.name_error(e, metadata['model'])
|
|
73
|
-
rescue => e
|
|
73
|
+
rescue StandardError => e
|
|
74
74
|
@result_lines << parse_result.add_exception(e)
|
|
75
75
|
end
|
|
76
76
|
end
|
|
@@ -11,7 +11,7 @@ node(:class_name) do |template|
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
node(:humanized_class_name) do |template|
|
|
14
|
-
template.class.name.underscore.split('_').map
|
|
14
|
+
template.class.name.underscore.split('_').map(&:capitalize).join(' ')
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
node(:can_edit) do |template|
|
|
@@ -49,11 +49,11 @@ module ForemanTemplates
|
|
|
49
49
|
add_all_permissions_to_default_roles
|
|
50
50
|
|
|
51
51
|
menu :top_menu, :template_sync,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
:url_hash => { :controller => :template_syncs, :action => :index },
|
|
53
|
+
:caption => N_('Sync Templates'),
|
|
54
|
+
:parent => :hosts_menu,
|
|
55
|
+
:before => :ptables,
|
|
56
|
+
:turbolinks => false
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -20,14 +20,14 @@ namespace :templates do
|
|
|
20
20
|
verbose = ENV['verbose']
|
|
21
21
|
|
|
22
22
|
results = ForemanTemplates::TemplateImporter.new({
|
|
23
|
-
verbose:
|
|
24
|
-
repo:
|
|
25
|
-
branch:
|
|
26
|
-
prefix:
|
|
27
|
-
dirname:
|
|
28
|
-
filter:
|
|
23
|
+
verbose: verbose,
|
|
24
|
+
repo: ENV['repo'],
|
|
25
|
+
branch: ENV['branch'],
|
|
26
|
+
prefix: ENV['prefix'],
|
|
27
|
+
dirname: ENV['dirname'],
|
|
28
|
+
filter: ENV['filter'],
|
|
29
29
|
associate: ENV['associate'],
|
|
30
|
-
lock:
|
|
30
|
+
lock: ENV['lock'],
|
|
31
31
|
}).import!
|
|
32
32
|
pp(results[:results].map { |result| result.to_h(verbose) })
|
|
33
33
|
end
|
|
@@ -58,8 +58,8 @@ namespace :templates do
|
|
|
58
58
|
# * negate => negate query [false]
|
|
59
59
|
# * prefix => The string all templates to purge should ( or not ) begin with [Community ]
|
|
60
60
|
# * verbose => Print extra information during the run [false]
|
|
61
|
-
negate:
|
|
62
|
-
prefix:
|
|
61
|
+
negate: ENV['negate'],
|
|
62
|
+
prefix: ENV['prefix'],
|
|
63
63
|
verbose: ENV['verbose'],
|
|
64
64
|
}).purge!
|
|
65
65
|
end
|
|
@@ -89,6 +89,7 @@ namespace :foreman_templates do
|
|
|
89
89
|
begin
|
|
90
90
|
require 'rubocop/rake_task'
|
|
91
91
|
RuboCop::RakeTask.new(:rubocop_foreman_templates) do |task|
|
|
92
|
+
task.options = ['--config', ForemanTemplates::Engine.root.join('.rubocop.yml').to_s]
|
|
92
93
|
task.patterns = ["#{ForemanTemplates::Engine.root}/app/**/*.rb",
|
|
93
94
|
"#{ForemanTemplates::Engine.root}/lib/**/*.rb",
|
|
94
95
|
"#{ForemanTemplates::Engine.root}/test/**/*.rb"]
|
data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js
CHANGED
|
@@ -1,159 +1,116 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
|
|
5
5
|
import ForemanForm from 'foremanReact/components/common/forms/ForemanForm';
|
|
6
|
-
import
|
|
6
|
+
import {
|
|
7
|
+
useForemanLocation,
|
|
8
|
+
useForemanOrganization,
|
|
9
|
+
} from 'foremanReact/Root/Context/ForemanContext';
|
|
10
|
+
|
|
7
11
|
import SyncSettingsFields from '../SyncSettingFields';
|
|
8
12
|
import SyncTypeRadios from '../SyncTypeRadios';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
', '
|
|
36
|
-
)}`,
|
|
37
|
-
repoFormat(validationData.repo)
|
|
38
|
-
)
|
|
39
|
-
.required("can't be blank"),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
return memo;
|
|
43
|
-
},
|
|
44
|
-
{}
|
|
13
|
+
import { redirectToResult, syncFormSchema } from './NewTemplateSyncFormHelpers';
|
|
14
|
+
|
|
15
|
+
const NewTemplateSyncForm = ({
|
|
16
|
+
error,
|
|
17
|
+
submitForm,
|
|
18
|
+
importSettings,
|
|
19
|
+
exportSettings,
|
|
20
|
+
history,
|
|
21
|
+
validationData,
|
|
22
|
+
importUrl,
|
|
23
|
+
exportUrl,
|
|
24
|
+
initialValues,
|
|
25
|
+
userPermissions,
|
|
26
|
+
}) => {
|
|
27
|
+
const allowedSyncType = (currentUserPermissions, radioAttrs) =>
|
|
28
|
+
currentUserPermissions[radioAttrs.permission];
|
|
29
|
+
|
|
30
|
+
const radioButtons = [
|
|
31
|
+
{ label: 'Import', value: 'import', permission: 'import' },
|
|
32
|
+
{ label: 'Export', value: 'export', permission: 'export' },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const [syncType, setSyncType] = useState(
|
|
36
|
+
radioButtons.find(radioAttrs =>
|
|
37
|
+
allowedSyncType(userPermissions, radioAttrs)
|
|
38
|
+
).value
|
|
45
39
|
);
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
class NewTemplateSyncForm extends React.Component {
|
|
53
|
-
allowedSyncType = (userPermissions, radioAttrs) =>
|
|
54
|
-
this.props.userPermissions[radioAttrs.permission];
|
|
55
|
-
|
|
56
|
-
constructor(props) {
|
|
57
|
-
super(props);
|
|
58
|
-
|
|
59
|
-
this.radioButtons = [
|
|
60
|
-
{ label: 'Import', value: 'import', permission: 'import' },
|
|
61
|
-
{ label: 'Export', value: 'export', permission: 'export' },
|
|
62
|
-
];
|
|
63
|
-
|
|
64
|
-
this.state = {
|
|
65
|
-
syncType: this.radioButtons.find(radioAttrs =>
|
|
66
|
-
this.allowedSyncType(props.userPermissions, radioAttrs)
|
|
67
|
-
).value,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
updateSyncType = event => {
|
|
72
|
-
this.setState({ syncType: event.target.value });
|
|
41
|
+
const updateSyncType = event => {
|
|
42
|
+
setSyncType(event.target.value);
|
|
73
43
|
};
|
|
74
44
|
|
|
75
|
-
permitRadioButtons = buttons =>
|
|
45
|
+
const permitRadioButtons = buttons =>
|
|
76
46
|
buttons.filter(buttonAttrs =>
|
|
77
|
-
|
|
47
|
+
allowedSyncType(userPermissions, buttonAttrs)
|
|
78
48
|
);
|
|
79
49
|
|
|
80
|
-
initRadioButtons =
|
|
81
|
-
|
|
50
|
+
const initRadioButtons = templateSyncType =>
|
|
51
|
+
permitRadioButtons(radioButtons).map(buttonAttrs => ({
|
|
82
52
|
get checked() {
|
|
83
|
-
return
|
|
53
|
+
return buttonAttrs.value === templateSyncType;
|
|
84
54
|
},
|
|
85
|
-
onChange:
|
|
55
|
+
onChange: updateSyncType,
|
|
86
56
|
...buttonAttrs,
|
|
87
57
|
}));
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
controlLabel="Action type"
|
|
145
|
-
radios={this.initRadioButtons(this.state.syncType)}
|
|
146
|
-
/>
|
|
147
|
-
<SyncSettingsFields
|
|
148
|
-
importSettings={importSettings}
|
|
149
|
-
exportSettings={exportSettings}
|
|
150
|
-
syncType={this.state.syncType}
|
|
151
|
-
resetField={resetToDefault}
|
|
152
|
-
/>
|
|
153
|
-
</ForemanForm>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
59
|
+
const addTaxParams = (key, currentTax) => params => {
|
|
60
|
+
if (currentTax && currentTax.id) {
|
|
61
|
+
return { ...params, [key]: [currentTax.id] };
|
|
62
|
+
}
|
|
63
|
+
return params;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const addOrgParams = addTaxParams(
|
|
67
|
+
'organization_ids',
|
|
68
|
+
useForemanOrganization()
|
|
69
|
+
);
|
|
70
|
+
const addLocParams = addTaxParams('location_ids', useForemanLocation());
|
|
71
|
+
|
|
72
|
+
const resetToDefault = (fieldName, fieldValue) => resetFn =>
|
|
73
|
+
resetFn(fieldName, fieldValue);
|
|
74
|
+
|
|
75
|
+
const handleSubmit = (values, actions) => {
|
|
76
|
+
const url = syncType === 'import' ? importUrl : exportUrl;
|
|
77
|
+
return submitForm({
|
|
78
|
+
url,
|
|
79
|
+
values: compose(addLocParams, addOrgParams)(values[syncType]),
|
|
80
|
+
message: `Templates were ${syncType}ed.`,
|
|
81
|
+
item: 'TemplateSync',
|
|
82
|
+
actions,
|
|
83
|
+
successCallback: () =>
|
|
84
|
+
history.replace({ pathname: '/template_syncs/result' }),
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<ForemanForm
|
|
90
|
+
onSubmit={handleSubmit}
|
|
91
|
+
initialValues={initialValues}
|
|
92
|
+
validationSchema={syncFormSchema(
|
|
93
|
+
syncType,
|
|
94
|
+
{ import: importSettings, export: exportSettings },
|
|
95
|
+
validationData
|
|
96
|
+
)}
|
|
97
|
+
onCancel={redirectToResult(history)}
|
|
98
|
+
error={error}
|
|
99
|
+
>
|
|
100
|
+
<SyncTypeRadios
|
|
101
|
+
name="syncType"
|
|
102
|
+
controlLabel="Action type"
|
|
103
|
+
radios={initRadioButtons(syncType)}
|
|
104
|
+
/>
|
|
105
|
+
<SyncSettingsFields
|
|
106
|
+
importSettings={importSettings}
|
|
107
|
+
exportSettings={exportSettings}
|
|
108
|
+
syncType={syncType}
|
|
109
|
+
resetField={resetToDefault}
|
|
110
|
+
/>
|
|
111
|
+
</ForemanForm>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
157
114
|
|
|
158
115
|
NewTemplateSyncForm.propTypes = {
|
|
159
116
|
importSettings: PropTypes.array,
|
|
@@ -166,8 +123,6 @@ NewTemplateSyncForm.propTypes = {
|
|
|
166
123
|
exportUrl: PropTypes.string.isRequired,
|
|
167
124
|
importUrl: PropTypes.string.isRequired,
|
|
168
125
|
submitForm: PropTypes.func.isRequired,
|
|
169
|
-
currentLocation: PropTypes.object.isRequired,
|
|
170
|
-
currentOrganization: PropTypes.object.isRequired,
|
|
171
126
|
};
|
|
172
127
|
|
|
173
128
|
NewTemplateSyncForm.defaultProps = {
|
data/webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormHelpers.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as Yup from 'yup';
|
|
2
|
+
|
|
3
|
+
export const redirectToResult = history => () =>
|
|
4
|
+
history.push({ pathname: '/template_syncs/result' });
|
|
5
|
+
|
|
6
|
+
const repoFormat = formatAry => value => {
|
|
7
|
+
if (value === undefined) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const valid = formatAry
|
|
12
|
+
.map(item => value.startsWith(item))
|
|
13
|
+
.reduce((memo, item) => item || memo, false);
|
|
14
|
+
|
|
15
|
+
return value && valid;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const syncFormSchema = (syncType, settingsObj, validationData) => {
|
|
19
|
+
const schema = (settingsObj[syncType].asMutable() || []).reduce(
|
|
20
|
+
(memo, setting) => {
|
|
21
|
+
if (setting.name === 'repo') {
|
|
22
|
+
return {
|
|
23
|
+
...memo,
|
|
24
|
+
repo: Yup.string()
|
|
25
|
+
.test(
|
|
26
|
+
'repo-format',
|
|
27
|
+
`Invalid repo format, must start with one of: ${validationData.repo.join(
|
|
28
|
+
', '
|
|
29
|
+
)}`,
|
|
30
|
+
repoFormat(validationData.repo)
|
|
31
|
+
)
|
|
32
|
+
.required("can't be blank"),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return memo;
|
|
36
|
+
},
|
|
37
|
+
{}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return Yup.object().shape({
|
|
41
|
+
[syncType]: Yup.object().shape(schema),
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -2,8 +2,6 @@ import { connect } from 'react-redux';
|
|
|
2
2
|
|
|
3
3
|
import * as FormActions from 'foremanReact/redux/actions/common/forms';
|
|
4
4
|
|
|
5
|
-
import { selectLayout } from 'foremanReact/components/Layout/LayoutSelectors';
|
|
6
|
-
|
|
7
5
|
import NewTemplateSyncForm from './NewTemplateSyncForm';
|
|
8
6
|
|
|
9
7
|
import {
|
|
@@ -24,8 +22,6 @@ const mapStateToProps = (state, ownProps) => {
|
|
|
24
22
|
initialValues: { ...initialFormValues },
|
|
25
23
|
importSettings,
|
|
26
24
|
exportSettings,
|
|
27
|
-
currentOrganization: selectLayout(state).currentOrganization,
|
|
28
|
-
currentLocation: selectLayout(state).currentLocation,
|
|
29
25
|
};
|
|
30
26
|
};
|
|
31
27
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_templates
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 9.0
|
|
4
|
+
version: 9.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Greg Sutcliffe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-05-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: diffy
|
|
@@ -96,6 +96,7 @@ files:
|
|
|
96
96
|
- package.json
|
|
97
97
|
- webpack/ForemanTemplates.js
|
|
98
98
|
- webpack/Routes.js
|
|
99
|
+
- webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js
|
|
99
100
|
- webpack/__mocks__/foremanReact/common/helpers.js
|
|
100
101
|
- webpack/__mocks__/foremanReact/components/Layout/LayoutSelectors.js
|
|
101
102
|
- webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js
|
|
@@ -120,6 +121,7 @@ files:
|
|
|
120
121
|
- webpack/components/NewTemplateSync/__tests__/__snapshots__/NewTemplateSyncSelectors.test.js.snap
|
|
121
122
|
- webpack/components/NewTemplateSync/components/ButtonTooltip.js
|
|
122
123
|
- webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncForm.js
|
|
124
|
+
- webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormHelpers.js
|
|
123
125
|
- webpack/components/NewTemplateSync/components/NewTemplateSyncForm/NewTemplateSyncFormSelectors.js
|
|
124
126
|
- webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/NewTemplateSyncFormSelectors.test.js
|
|
125
127
|
- webpack/components/NewTemplateSync/components/NewTemplateSyncForm/__tests__/__snapshots__/NewTemplateSyncFormSelectors.test.js.snap
|