foreman_ansible 2.3.2 → 2.3.3
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/assets/stylesheets/foreman_ansible/foreman-ansible.css +4 -0
- data/app/controllers/ansible_variables_controller.rb +28 -6
- data/app/controllers/api/v2/ansible_variables_controller.rb +9 -1
- data/app/controllers/concerns/foreman/controller/parameters/ansible_variable.rb +2 -1
- data/app/controllers/ui_ansible_roles_controller.rb +14 -0
- data/app/helpers/foreman_ansible/ansible_roles_helper.rb +19 -1
- data/app/models/ansible_role.rb +1 -0
- data/app/models/ansible_variable.rb +8 -3
- data/app/services/foreman_ansible/variables_importer.rb +61 -30
- data/app/views/ansible_roles/welcome.html.erb +1 -1
- data/app/views/ansible_variables/_fields.erb +12 -5
- data/app/views/ansible_variables/import.html.erb +4 -1
- data/app/views/ansible_variables/index.html.erb +8 -3
- data/app/views/ansible_variables/new.html.erb +17 -0
- data/app/views/api/v2/ansible_variables/create.json.rabl +3 -0
- data/app/views/api/v2/ansible_variables/show.json.rabl +1 -1
- data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +13 -13
- data/app/views/ui_ansible_roles/index.json.rabl +3 -0
- data/app/views/ui_ansible_roles/main.json.rabl +3 -0
- data/app/views/ui_ansible_roles/show.json.rabl +3 -0
- data/config/routes.rb +4 -2
- data/db/migrate/20190318094437_add_imported_attr_to_ansible_variables.rb +15 -0
- data/lib/foreman_ansible/register.rb +13 -2
- data/lib/foreman_ansible/version.rb +1 -1
- data/package.json +50 -9
- data/test/factories/ansible_variables.rb +1 -0
- data/test/functional/ansible_variables_controller_test.rb +10 -0
- data/test/functional/api/v2/ansible_variables_controller_test.rb +10 -0
- data/test/functional/ui_ansible_roles_controller_test.rb +14 -0
- data/test/unit/services/ansible_variables_importer_test.rb +20 -3
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/EmptyState.js +5 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.js +140 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcher.scss +45 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherActions.js +69 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherConstants.js +7 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherHelpers.js +7 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherReducer.js +69 -0
- data/webpack/components/AnsibleRolesSwitcher/AnsibleRolesSwitcherSelectors.js +68 -0
- data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesData.fixtures.js +20 -0
- data/webpack/components/AnsibleRolesSwitcher/__fixtures__/ansibleRolesSwitcherReducer.fixtures.js +36 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcher.test.js +30 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherReducer.test.js +73 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/AnsibleRolesSwitcherSelectors.test.js +43 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcher.test.js.snap +79 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherReducer.test.js.snap +399 -0
- data/webpack/components/AnsibleRolesSwitcher/__tests__/__snapshots__/AnsibleRolesSwitcherSelectors.test.js.snap +60 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.js +33 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsiblePermissionDenied.test.js +9 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.js +56 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRole.test.js +26 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRoleActionButton.js +16 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AnsibleRolesSwitcherError.js +32 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.js +67 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AssignedRolesList.test.js +19 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.js +52 -0
- data/webpack/components/AnsibleRolesSwitcher/components/AvailableRolesList.test.js +22 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsiblePermissionDenied.test.js.snap +26 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AnsibleRole.test.js.snap +108 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AssignedRolesList.test.js.snap +64 -0
- data/webpack/components/AnsibleRolesSwitcher/components/__snapshots__/AvailableRolesList.test.js.snap +54 -0
- data/webpack/components/AnsibleRolesSwitcher/components/withProtectedView.js +14 -0
- data/webpack/components/AnsibleRolesSwitcher/index.js +44 -0
- data/webpack/components/ReportJsonViewer.js +11 -7
- data/webpack/index.js +14 -1
- data/webpack/reducer.js +7 -0
- data/webpack/test_setup.js +11 -0
- metadata +46 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1bc81f85be7efbc4ebb9636fc9bd550d54fb22f3
|
|
4
|
+
data.tar.gz: d89aa3d74ffb81ed88a678e5f139530bdec076aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 853c086e4c7a344844c2da7360221030dba7ea21fd9d65d0f387b3c76825af7b2bae258ca8914eeaecfee5756ca99fbfc0d6bf7580e96dff2f458a3e9d449162
|
|
7
|
+
data.tar.gz: af2d1693fc63a41a202a2de837a9ae678b1400fc5c5c3eda567d4211e7244ac4036880d061fa74681052b277f356f33840d25f1845f92c5f02cc599f318b3103
|
|
@@ -18,6 +18,19 @@ class AnsibleVariablesController < ::LookupKeysController
|
|
|
18
18
|
:per_page => params[:per_page])
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
def new
|
|
22
|
+
@ansible_variable = AnsibleVariable.new
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def create
|
|
26
|
+
@ansible_variable = AnsibleVariable.new(ansible_variable_params.merge(:imported => false))
|
|
27
|
+
if @ansible_variable.save
|
|
28
|
+
process_success
|
|
29
|
+
else
|
|
30
|
+
process_error
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
21
34
|
def import
|
|
22
35
|
import_roles = @importer_roles.import_role_names
|
|
23
36
|
import_roles[:new_roles] = import_roles[:new]
|
|
@@ -27,11 +40,12 @@ class AnsibleVariablesController < ::LookupKeysController
|
|
|
27
40
|
end
|
|
28
41
|
|
|
29
42
|
def confirm_import
|
|
30
|
-
results = @importer.finish_import(new_vars, old_vars)
|
|
31
|
-
|
|
43
|
+
results = @importer.finish_import(new_vars, old_vars, updated_vars)
|
|
44
|
+
success _(
|
|
32
45
|
"Import of variables successfully finished.\n"\
|
|
33
|
-
"Added: #{results[:added].
|
|
34
|
-
"Removed: #{results[:obsolete].
|
|
46
|
+
"Added: #{results[:added].count} \n "\
|
|
47
|
+
"Removed: #{results[:obsolete].count} \n"\
|
|
48
|
+
"Updated: #{results[:updated].count}"
|
|
35
49
|
)
|
|
36
50
|
redirect_to ansible_variables_path
|
|
37
51
|
end
|
|
@@ -49,11 +63,19 @@ class AnsibleVariablesController < ::LookupKeysController
|
|
|
49
63
|
end
|
|
50
64
|
|
|
51
65
|
def new_vars
|
|
52
|
-
|
|
66
|
+
fetch_vars :new
|
|
53
67
|
end
|
|
54
68
|
|
|
55
69
|
def old_vars
|
|
56
|
-
|
|
70
|
+
fetch_vars :obsolete
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def updated_vars
|
|
74
|
+
fetch_vars :update
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def fetch_vars(key)
|
|
78
|
+
params.fetch(:changed, {}).fetch(key, {}).try(:as_json) || {}
|
|
57
79
|
end
|
|
58
80
|
|
|
59
81
|
def import_new_roles
|
|
@@ -6,6 +6,7 @@ module Api
|
|
|
6
6
|
class AnsibleVariablesController < ::Api::V2::BaseController
|
|
7
7
|
include ::Api::Version2
|
|
8
8
|
include Foreman::Controller::Parameters::VariableLookupKey
|
|
9
|
+
include Foreman::Controller::Parameters::AnsibleVariable
|
|
9
10
|
|
|
10
11
|
resource_description do
|
|
11
12
|
api_version 'v2'
|
|
@@ -36,7 +37,7 @@ module Api
|
|
|
36
37
|
def_param_group :ansible_variable do
|
|
37
38
|
param :ansible_variable, Hash, :required => true, :action_aware => true do
|
|
38
39
|
param :variable, String, :required => true, :desc => N_("Name of variable")
|
|
39
|
-
param :ansible_role_id, :number, :desc => N_("Role ID")
|
|
40
|
+
param :ansible_role_id, :number, :required => true, :desc => N_("Role ID")
|
|
40
41
|
param :default_value, :any_type, :of => LookupKey::KEY_TYPES, :desc => N_("Default value of variable")
|
|
41
42
|
param :hidden_value, :bool, :desc => N_("When enabled the parameter is hidden in the UI")
|
|
42
43
|
param :override_value_order, String, :desc => N_("The order in which values are resolved")
|
|
@@ -50,6 +51,13 @@ module Api
|
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
|
|
54
|
+
api :POST, '/ansible_variables', N_('Create Ansible variable')
|
|
55
|
+
param_group :ansible_variable, :as => :create
|
|
56
|
+
def create
|
|
57
|
+
@ansible_variable = AnsibleVariable.new(ansible_variable_params.merge(:imported => false))
|
|
58
|
+
process_response @ansible_variable.save
|
|
59
|
+
end
|
|
60
|
+
|
|
53
61
|
api :PUT, '/ansible_variables/:id', N_('Updates Ansible variable')
|
|
54
62
|
param :id, :identifier, :required => true
|
|
55
63
|
param_group :ansible_variable, :as => :update
|
|
@@ -11,7 +11,8 @@ module Foreman
|
|
|
11
11
|
class_methods do
|
|
12
12
|
def ansible_variable_params_filter
|
|
13
13
|
Foreman::ParameterFilter.new(::AnsibleVariable).tap do |filter|
|
|
14
|
-
filter.permit :
|
|
14
|
+
filter.permit :imported, :ansible_role_id,
|
|
15
|
+
:ansible_roles => [], :ansible_role_ids => [],
|
|
15
16
|
:ansible_role_names => [],
|
|
16
17
|
:param_classes => [], :param_classes_ids => [],
|
|
17
18
|
:param_classes_names => []
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class UiAnsibleRolesController < ::Api::V2::BaseController
|
|
2
|
+
def resource_name(resource = 'AnsibleRole')
|
|
3
|
+
super resource
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
@ui_ansible_roles = resource_scope_for_index(:permission => :view_ansible_roles)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# restore original method from find_common to ignore resource nesting
|
|
11
|
+
def resource_scope(options = {})
|
|
12
|
+
@resource_scope ||= scope_for(resource_class, options)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -5,12 +5,26 @@ module ForemanAnsible
|
|
|
5
5
|
module AnsibleRolesHelper
|
|
6
6
|
def ansible_proxy_links(hash, classes = nil)
|
|
7
7
|
SmartProxy.with_features('Ansible').map do |proxy|
|
|
8
|
-
display_link_if_authorized(_('
|
|
8
|
+
display_link_if_authorized(_('Import from %s') % proxy.name,
|
|
9
9
|
hash.merge(:proxy => proxy),
|
|
10
10
|
:class => classes)
|
|
11
11
|
end.flatten
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
def ansible_role_select(f, persisted)
|
|
15
|
+
blank_opt = persisted ? {} : { :include_blank => true }
|
|
16
|
+
select_items = persisted ? [f.object.ansible_role] : AnsibleRole.order(:name)
|
|
17
|
+
select_f f,
|
|
18
|
+
:ansible_role_id,
|
|
19
|
+
select_items,
|
|
20
|
+
:id,
|
|
21
|
+
:to_label,
|
|
22
|
+
blank_opt,
|
|
23
|
+
:label => _("Ansible Role"),
|
|
24
|
+
:disabled => persisted,
|
|
25
|
+
:required => true
|
|
26
|
+
end
|
|
27
|
+
|
|
14
28
|
def ansible_proxy_import(hash)
|
|
15
29
|
select_action_button(_('Import'),
|
|
16
30
|
{ :primary => true, :class => 'roles-import' },
|
|
@@ -20,5 +34,9 @@ module ForemanAnsible
|
|
|
20
34
|
def import_time(role)
|
|
21
35
|
_('%s ago') % time_ago_in_words(role.updated_at)
|
|
22
36
|
end
|
|
37
|
+
|
|
38
|
+
def roles_attrs(roles)
|
|
39
|
+
roles.map { |item| { :id => item.id, :name => item.name } }
|
|
40
|
+
end
|
|
23
41
|
end
|
|
24
42
|
end
|
data/app/models/ansible_role.rb
CHANGED
|
@@ -17,6 +17,7 @@ class AnsibleRole < ApplicationRecord
|
|
|
17
17
|
:class_name => 'AnsibleVariable'
|
|
18
18
|
|
|
19
19
|
scoped_search :on => :name, :complete_value => true
|
|
20
|
+
scoped_search :on => :id, :complete_value => false
|
|
20
21
|
scoped_search :on => :updated_at
|
|
21
22
|
scoped_search :relation => :hosts,
|
|
22
23
|
:on => :id, :rename => :host_id, :only_explicit => true
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
# Represents the variables used in Ansible to parameterize playbooks
|
|
4
4
|
class AnsibleVariable < LookupKey
|
|
5
5
|
belongs_to :ansible_role, :inverse_of => :ansible_variables
|
|
6
|
-
validates :
|
|
6
|
+
validates :ansible_role_id, :presence => true
|
|
7
7
|
scoped_search :on => :key, :aliases => [:name], :complete_value => true
|
|
8
|
+
scoped_search :on => :imported, :complete_value => { :true => true, :false => false }
|
|
8
9
|
scoped_search :relation => :ansible_role, :on => :name,
|
|
9
10
|
:complete_value => true, :rename => :ansible_role
|
|
10
11
|
|
|
@@ -12,8 +13,12 @@ class AnsibleVariable < LookupKey
|
|
|
12
13
|
true
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
def self.humanize_class_name
|
|
16
|
-
|
|
16
|
+
def self.humanize_class_name(options = nil)
|
|
17
|
+
if options.present?
|
|
18
|
+
super
|
|
19
|
+
else
|
|
20
|
+
"Ansible variable"
|
|
21
|
+
end
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
def editable_by_user?
|
|
@@ -6,6 +6,17 @@ module ForemanAnsible
|
|
|
6
6
|
class VariablesImporter
|
|
7
7
|
include ::ForemanAnsible::ProxyAPI
|
|
8
8
|
|
|
9
|
+
VARIABLE_TYPES = {
|
|
10
|
+
'TrueClass' => 'boolean',
|
|
11
|
+
'FalseClass' => 'boolean',
|
|
12
|
+
'Integer' => 'integer',
|
|
13
|
+
'Fixnum' => 'integer',
|
|
14
|
+
'Float' => 'real',
|
|
15
|
+
'Array' => 'array',
|
|
16
|
+
'Hash' => 'hash',
|
|
17
|
+
'String' => 'string'
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
9
20
|
def initialize(proxy = nil)
|
|
10
21
|
@ansible_proxy = proxy
|
|
11
22
|
end
|
|
@@ -34,11 +45,15 @@ module ForemanAnsible
|
|
|
34
45
|
end
|
|
35
46
|
|
|
36
47
|
def initialize_variables(variables, role)
|
|
37
|
-
variables.map do |
|
|
48
|
+
variables.map do |variable_name, variable_default|
|
|
38
49
|
variable = AnsibleVariable.find_or_initialize_by(
|
|
39
|
-
:key =>
|
|
40
|
-
# :key_type, :default_value, :required
|
|
50
|
+
:key => variable_name
|
|
41
51
|
)
|
|
52
|
+
if variable.new_record?
|
|
53
|
+
variable.assign_attributes(:default_value => variable_default,
|
|
54
|
+
:key_type => infer_key_type(variable_default),
|
|
55
|
+
:imported => true)
|
|
56
|
+
end
|
|
42
57
|
variable.ansible_role = role
|
|
43
58
|
variable.valid? ? variable : nil
|
|
44
59
|
end
|
|
@@ -46,45 +61,48 @@ module ForemanAnsible
|
|
|
46
61
|
|
|
47
62
|
def detect_changes(imported)
|
|
48
63
|
changes = {}.with_indifferent_access
|
|
49
|
-
|
|
50
|
-
changes[:
|
|
64
|
+
persisted, changes[:new] = imported.partition { |role| role.id.present? }
|
|
65
|
+
changes[:update], _old = persisted.partition(&:changed?)
|
|
66
|
+
changes[:obsolete] = AnsibleVariable.where.not(:id => persisted.pluck(:id), :imported => false)
|
|
51
67
|
changes
|
|
52
68
|
end
|
|
53
69
|
|
|
54
|
-
def finish_import(new, obsolete)
|
|
55
|
-
results = { :added => [], :obsolete => [] }
|
|
70
|
+
def finish_import(new, obsolete, update)
|
|
71
|
+
results = { :added => [], :obsolete => [], :updated => [] }
|
|
56
72
|
results[:added] = create_new_variables(new) if new.present?
|
|
57
73
|
results[:obsolete] = delete_old_variables(obsolete) if obsolete.present?
|
|
74
|
+
results[:updated] = update_variables(update) if update.present?
|
|
58
75
|
results
|
|
59
76
|
end
|
|
60
77
|
|
|
61
|
-
def create_new_variables(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
variable.save
|
|
70
|
-
added << variable.key
|
|
71
|
-
end
|
|
78
|
+
def create_new_variables(variables)
|
|
79
|
+
iterate_over_variables(variables) do |role, memo, attrs|
|
|
80
|
+
variable = AnsibleVariable.new(
|
|
81
|
+
JSON.parse(attrs)['ansible_variable']
|
|
82
|
+
)
|
|
83
|
+
variable.ansible_role = ::AnsibleRole.find_by(:name => role)
|
|
84
|
+
variable.save
|
|
85
|
+
memo << variable
|
|
72
86
|
end
|
|
73
|
-
added
|
|
74
87
|
end
|
|
75
88
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
def update_variables(variables)
|
|
90
|
+
iterate_over_variables(variables) do |_role, memo, attrs|
|
|
91
|
+
attributes = JSON.parse(attrs)['ansible_variable']
|
|
92
|
+
var = AnsibleVariable.find attributes['id']
|
|
93
|
+
var.update(attributes)
|
|
94
|
+
memo << var
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def delete_old_variables(variables)
|
|
99
|
+
iterate_over_variables(variables) do |_role, memo, attrs|
|
|
100
|
+
variable = AnsibleVariable.find(
|
|
101
|
+
JSON.parse(attrs)['ansible_variable']['id']
|
|
102
|
+
)
|
|
103
|
+
memo << variable.key
|
|
104
|
+
variable.destroy
|
|
86
105
|
end
|
|
87
|
-
removed
|
|
88
106
|
end
|
|
89
107
|
|
|
90
108
|
private
|
|
@@ -96,5 +114,18 @@ module ForemanAnsible
|
|
|
96
114
|
def remote_variables
|
|
97
115
|
proxy_api.all_variables
|
|
98
116
|
end
|
|
117
|
+
|
|
118
|
+
def infer_key_type(value)
|
|
119
|
+
VARIABLE_TYPES[value.class.to_s] || 'string'
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def iterate_over_variables(variables)
|
|
123
|
+
variables.reduce([]) do |memo, (role, vars)|
|
|
124
|
+
vars.map do |_key, attrs|
|
|
125
|
+
yield role, memo, attrs if block_given?
|
|
126
|
+
memo
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
99
130
|
end
|
|
100
131
|
end
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p><%= _('No ansible roles were found in Foreman. If you want to assign roles to your hosts,
|
|
8
8
|
you have to import them first.').html_safe %>
|
|
9
9
|
</p>
|
|
10
|
-
<p><%= link_to(_('Learn more about this in the documentation.'), documentation_url('#4.1ImportingRoles', :root_url => ansible_doc_url)) %></p>
|
|
10
|
+
<p><%= link_to(_('Learn more about this in the documentation.'), documentation_url('#4.1ImportingRoles', :root_url => ansible_doc_url), target: '_blank') %></p>
|
|
11
11
|
<div class="blank-slate-pf-secondary-action">
|
|
12
12
|
<%= ansible_proxy_import(hash_for_import_ansible_roles_path) %>
|
|
13
13
|
</div>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<div id='<%= f.object.to_param %>' class='tab-pane fields'>
|
|
2
2
|
<fieldset>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<%= f
|
|
3
|
+
<% is_imported = f.object.new_record? ? false : f.object.imported %>
|
|
4
|
+
<h2><%= is_imported ? _("Ansible Variable Details (Imported)") : _("Ansible Variable Details")%></h2>
|
|
5
|
+
<%= text_f f, :key, :disabled => f.object.persisted?, :size => "col-md-8" %>
|
|
6
6
|
<%= textarea_f f, :description, :rows => :auto, :size => "col-md-8", :class => "no-stretch" %>
|
|
7
|
-
<%=
|
|
7
|
+
<%= ansible_role_select f, f.object.persisted? %>
|
|
8
|
+
|
|
8
9
|
</fieldset>
|
|
9
10
|
<fieldset>
|
|
10
11
|
<h2><%= _("Default Behavior") %></h2>
|
|
@@ -12,7 +13,13 @@
|
|
|
12
13
|
<%= checkbox_f(f, :override, :onchange => 'toggleOverrideValue(this)', :size => "col-md-8",
|
|
13
14
|
:label_help => _('Mark the variable to be managed by Foreman. When the Ansible role of this variable is assigned to a host, the default value will be added to Ansible inventory as a host variable. Specify matchers to set a different value for such variable.')
|
|
14
15
|
) %>
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
<% version = Foreman::Version.new %>
|
|
18
|
+
<% if version.major.to_i >= 1 && version.minor.to_i >= 22 %>
|
|
19
|
+
<%= param_type_selector(f, false, :onchange => 'keyTypeChange(this)', :disabled => !f.object.override) %>
|
|
20
|
+
<% else %>
|
|
21
|
+
<%= param_type_selector(f, :onchange => 'keyTypeChange(this)', :disabled => !f.object.override) %>
|
|
22
|
+
<% end %>
|
|
16
23
|
<%= textarea_f f, :default_value, :value => f.object.default_value_before_type_cast, :size => "col-md-8",
|
|
17
24
|
:disabled => (!f.object.override || f.object.omit),
|
|
18
25
|
:input_group_btn => fullscreen_input,
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
<%= link_to_function(icon_text("check", _("Obsolete")),
|
|
10
10
|
"toggleCheckboxesBySelector('.variable_select_boxes_obsolete')",
|
|
11
11
|
:title => _("Check/Uncheck obsolete")) %>
|
|
12
|
+
<%= link_to_function(icon_text("check", _("Update")),
|
|
13
|
+
"toggleCheckboxesBySelector('.variable_select_boxes_update')",
|
|
14
|
+
:title => _("Check/Uncheck update")) %>
|
|
12
15
|
</h6>
|
|
13
16
|
<table class="<%= table_css_classes %>">
|
|
14
17
|
<thead>
|
|
@@ -39,7 +42,7 @@
|
|
|
39
42
|
<td><%= variable.ansible_role.hosts.count %></td>
|
|
40
43
|
<td><%= variable.ansible_role.hostgroups.count %></td>
|
|
41
44
|
<td>
|
|
42
|
-
<%= { "new" => _("Add"), "obsolete" => _("Remove") }[kind] %>
|
|
45
|
+
<%= { "new" => _("Add"), "obsolete" => _("Remove"), "update" => _("Update") }[kind] %>
|
|
43
46
|
</td>
|
|
44
47
|
</tr>
|
|
45
48
|
<% end %>
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
<% title _("Ansible Variables") %>
|
|
2
|
+
<%= stylesheet 'foreman_ansible/foreman-ansible' %>
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
<%= title_actions ansible_proxy_import(hash_for_import_ansible_variables_path),
|
|
5
|
+
display_link_if_authorized(_('New Ansible Variable'), hash_for_new_ansible_variable_path, :class => "btn btn-default no-float"),
|
|
6
|
+
documentation_button('#4.3Variables', :root_url => ansible_doc_url)
|
|
7
|
+
%>
|
|
5
8
|
|
|
6
9
|
<table class="<%= table_css_classes 'table-fixed' %>">
|
|
7
10
|
<thead>
|
|
8
11
|
<tr>
|
|
9
12
|
<th class='col-md-6'><%= sort :name, :as => s_('Variable|Name') %></th>
|
|
10
13
|
<th class='col-md-2'><%= sort :ansible_role, :as => s_('Variable|Role') %></th>
|
|
11
|
-
<th class='col-md-
|
|
14
|
+
<th class='col-md-1'><%= _('Type') %></th>
|
|
15
|
+
<th class='col-md-1'><%= sort :imported, :as => _('Imported?') %></th>
|
|
12
16
|
<th class='col-md-2'><%= _('Actions') %></th>
|
|
13
17
|
</tr>
|
|
14
18
|
</thead>
|
|
@@ -27,6 +31,7 @@
|
|
|
27
31
|
hash_for_ansible_variables_path(:search => "ansible_role = #{variable.ansible_role}")
|
|
28
32
|
) %></td>
|
|
29
33
|
<td class="ellipsis"><%= variable.key_type || 'string' %></td>
|
|
34
|
+
<td align='center'><%= checked_icon variable.imported %></td>
|
|
30
35
|
<td class="ellipsis">
|
|
31
36
|
<% links = [
|
|
32
37
|
display_delete_if_authorized(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%= breadcrumbs(
|
|
2
|
+
:items => [
|
|
3
|
+
{
|
|
4
|
+
:caption => _('Ansible Variables'),
|
|
5
|
+
:url => url_for(ansible_variables_path)
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
:caption => _('Create Ansible Variable')
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
:switchable => false
|
|
12
|
+
) %>
|
|
13
|
+
<% title(_('Create Ansible Variable')) %>
|
|
14
|
+
<%= form_for(@ansible_variable) do |f| %>
|
|
15
|
+
<%= render 'fields', :f => f %>
|
|
16
|
+
<%= submit_or_cancel f %>
|
|
17
|
+
<% end %>
|
|
@@ -5,7 +5,7 @@ attributes :id, :variable, :ansible_role, :ansible_role_id, :description, :overr
|
|
|
5
5
|
:variable_type, :hidden_value?, :validator_type,
|
|
6
6
|
:validator_rule, :merge_overrides, :merge_default,
|
|
7
7
|
:avoid_duplicates, :override_value_order, :created_at, :updated_at,
|
|
8
|
-
:default_value
|
|
8
|
+
:default_value, :imported
|
|
9
9
|
|
|
10
10
|
node do |ansible_variable|
|
|
11
11
|
{
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
+
<%= webpacked_plugins_js_for :foreman_ansible %>
|
|
2
|
+
<%= webpacked_plugins_css_for :foreman_ansible %>
|
|
3
|
+
|
|
1
4
|
<div class='tab-pane' id='ansible_roles'>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'or by clicking on the Play Roles button on the Host page ').html_safe
|
|
13
|
-
},
|
|
14
|
-
{ 'data-inheriteds' => f.object.inherited_ansible_roles.map(&:id).to_json }) %>
|
|
5
|
+
<div id='ansible_roles_switcher'></div>
|
|
6
|
+
<% roles = f.object.is_a?(Hostgroup) ? roles_attrs(f.object.inherited_and_own_ansible_roles) : roles_attrs(f.object.all_ansible_roles) %>
|
|
7
|
+
<% class_name = f.object.is_a?(Hostgroup) ? 'Hostgroup' : 'Host' %>
|
|
8
|
+
<%= mount_react_component('AnsibleRolesSwitcher', '#ansible_roles_switcher', { :initialAssignedRoles => roles,
|
|
9
|
+
:inheritedRoleIds => f.object.inherited_ansible_roles.map(&:id),
|
|
10
|
+
:availableRolesUrl => ui_ansible_roles_path,
|
|
11
|
+
:resourceId => f.object.id,
|
|
12
|
+
:resourceName => class_name,
|
|
13
|
+
:canView => User.current.can?(:view_ansible_roles)
|
|
14
|
+
}.to_json) %>
|
|
15
15
|
</div>
|
data/config/routes.rb
CHANGED
|
@@ -58,7 +58,9 @@ Rails.application.routes.draw do
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
resources :
|
|
61
|
+
resources :ui_ansible_roles, :only => [:index]
|
|
62
|
+
|
|
63
|
+
resources :ansible_variables, :except => [:show] do
|
|
62
64
|
resources :lookup_values, :only => [:index, :create, :update, :destroy]
|
|
63
65
|
collection do
|
|
64
66
|
get :import
|
|
@@ -82,7 +84,7 @@ Rails.application.routes.draw do
|
|
|
82
84
|
end
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
resources :ansible_variables, :only => [:show, :index, :destroy, :update] do
|
|
87
|
+
resources :ansible_variables, :only => [:show, :index, :destroy, :update, :create] do
|
|
86
88
|
collection do
|
|
87
89
|
put :import
|
|
88
90
|
put :obsolete
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class AddImportedAttrToAnsibleVariables < ActiveRecord::Migration[5.2]
|
|
2
|
+
def up
|
|
3
|
+
add_column :lookup_keys, :imported, :boolean
|
|
4
|
+
|
|
5
|
+
AnsibleVariable.find_in_batches do |batch|
|
|
6
|
+
batch.map do |variable|
|
|
7
|
+
variable.update_attribute :imported, true
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def down
|
|
13
|
+
remove_column :lookup_keys, :imported
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# rubocop:disable BlockLength
|
|
4
4
|
Foreman::Plugin.register :foreman_ansible do
|
|
5
|
-
requires_foreman '>= 1.
|
|
5
|
+
requires_foreman '>= 1.21'
|
|
6
6
|
|
|
7
7
|
security_block :foreman_ansible do
|
|
8
8
|
permission :play_roles_on_host,
|
|
@@ -17,7 +17,8 @@ Foreman::Plugin.register :foreman_ansible do
|
|
|
17
17
|
:resource_type => 'Hostgroup'
|
|
18
18
|
permission :view_ansible_roles,
|
|
19
19
|
{ :ansible_roles => [:index, :auto_complete_search],
|
|
20
|
-
:'api/v2/ansible_roles' => [:index, :show, :fetch]
|
|
20
|
+
:'api/v2/ansible_roles' => [:index, :show, :fetch],
|
|
21
|
+
:ui_ansible_roles => [:index] },
|
|
21
22
|
:resource_type => 'AnsibleRole'
|
|
22
23
|
permission :destroy_ansible_roles,
|
|
23
24
|
{ :ansible_roles => [:destroy],
|
|
@@ -44,6 +45,12 @@ Foreman::Plugin.register :foreman_ansible do
|
|
|
44
45
|
:'api/v2/ansible_variables' => [:destroy, :obsolete]
|
|
45
46
|
},
|
|
46
47
|
:resource_type => 'AnsibleVariable'
|
|
48
|
+
permission :create_ansible_variables,
|
|
49
|
+
{
|
|
50
|
+
:ansible_variables => [:new, :create],
|
|
51
|
+
:'api/v2/ansible_variables' => [:create]
|
|
52
|
+
},
|
|
53
|
+
:resource_type => 'AnsibleVariable'
|
|
47
54
|
permission :import_ansible_variables,
|
|
48
55
|
{
|
|
49
56
|
:ansible_variables => [:import, :confirm_import],
|
|
@@ -69,6 +76,10 @@ Foreman::Plugin.register :foreman_ansible do
|
|
|
69
76
|
:view_ansible_roles, :destroy_ansible_roles,
|
|
70
77
|
:import_ansible_roles]
|
|
71
78
|
|
|
79
|
+
role 'Ansible Tower Inventory Reader',
|
|
80
|
+
[:view_hosts, :view_hostgroups, :view_facts],
|
|
81
|
+
'Permissions required for the user which is used by Ansible Tower Dynamic Inventory Item'
|
|
82
|
+
|
|
72
83
|
add_all_permissions_to_default_roles
|
|
73
84
|
extend_template_helpers ForemanAnsible::RendererMethods
|
|
74
85
|
allowed_template_helpers :insights_remediation
|