foreman_ansible 2.3.0 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -4
- data/app/controllers/api/v2/ansible_override_values_controller.rb +53 -0
- data/app/controllers/api/v2/ansible_roles_controller.rb +2 -1
- data/app/controllers/api/v2/ansible_variables_controller.rb +32 -4
- data/app/controllers/concerns/foreman/controller/parameters/ansible_override_value.rb +36 -0
- data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +56 -37
- data/app/services/foreman_ansible/inventory_creator.rb +10 -5
- data/app/services/foreman_ansible/operating_system_parser.rb +10 -0
- data/app/services/foreman_ansible/roles_importer.rb +1 -2
- data/app/views/ansible_variables/index.html.erb +1 -1
- data/app/views/api/v2/ansible_override_values/show.json.rabl +3 -0
- data/app/views/api/v2/ansible_variables/destroy.json.rabl +3 -0
- data/app/views/api/v2/ansible_variables/show.json.rabl +5 -4
- data/config/routes.rb +3 -1
- data/lib/foreman_ansible/engine.rb +2 -2
- data/lib/foreman_ansible/version.rb +1 -1
- data/locale/action_names.rb +3 -3
- data/locale/de/foreman_ansible.edit.po +238 -87
- data/locale/de/foreman_ansible.po +77 -2
- data/locale/en/foreman_ansible.edit.po +238 -87
- data/locale/en/foreman_ansible.po +77 -2
- data/locale/es/foreman_ansible.edit.po +238 -87
- data/locale/es/foreman_ansible.po +77 -2
- data/locale/foreman_ansible.pot +126 -24
- data/locale/fr/foreman_ansible.edit.po +238 -87
- data/locale/fr/foreman_ansible.po +77 -2
- data/locale/it/foreman_ansible.edit.po +238 -87
- data/locale/it/foreman_ansible.po +77 -2
- data/locale/ja/foreman_ansible.edit.po +238 -87
- data/locale/ja/foreman_ansible.po +77 -2
- data/locale/ko/foreman_ansible.edit.po +238 -87
- data/locale/ko/foreman_ansible.po +77 -2
- data/locale/pt_BR/foreman_ansible.edit.po +238 -87
- data/locale/pt_BR/foreman_ansible.po +77 -2
- data/locale/ru/foreman_ansible.edit.po +238 -87
- data/locale/ru/foreman_ansible.po +77 -2
- data/locale/zh_CN/foreman_ansible.edit.po +238 -87
- data/locale/zh_CN/foreman_ansible.po +77 -2
- data/locale/zh_TW/foreman_ansible.edit.po +238 -87
- data/locale/zh_TW/foreman_ansible.po +77 -2
- data/test/functional/api/v2/ansible_roles_controller_test.rb +8 -7
- data/test/unit/services/fact_parser_test.rb +7 -3
- data/test/unit/services/inventory_creator_test.rb +15 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08c99d39eecf64143f22351c6320d62cfb1f3314'
|
4
|
+
data.tar.gz: 42133e0cf37fedd36eead1368ae2e05411cc9ab7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3d1e4d553a4621b0a40a19206369dcc3263cdbbb37ad81a23f2a65c36b2a3f06c7bb91d39f2e4f02051409b19be0323112b5949b2c3aeaa267304c5253e8090
|
7
|
+
data.tar.gz: 58a3841d303c241512ee7a8ff947f851fd55ed34132b482919bbea8d6a256262dc15a3b4a774cdc4a63a4575acd1aa94d9849ec9b9b7600f2ea14f4420cfba25
|
data/README.md
CHANGED
@@ -23,7 +23,7 @@ Reporting and facts import from Ansible to Foreman.
|
|
23
23
|
* Looking for an Ansible dynamic inventory for Foreman? Use [foreman_ansible_inventory](https://github.com/theforeman/foreman_ansible_inventory/)
|
24
24
|
|
25
25
|
## Documentation (installation and configuration)
|
26
|
-
Check out the official manual at [theforeman.org](http://theforeman.org/plugins/foreman_ansible/
|
26
|
+
Check out the official manual at [theforeman.org](http://theforeman.org/plugins/foreman_ansible/2.x/index.html)
|
27
27
|
|
28
28
|
##### Registering a new host in Foreman
|
29
29
|
![sign up gif](http://i.imgur.com/mlnVFJj.gif)
|
@@ -41,12 +41,14 @@ Check out the official manual at [theforeman.org](http://theforeman.org/plugins/
|
|
41
41
|
|
42
42
|
| Foreman | Plugin |
|
43
43
|
| ---------------:| --------------:|
|
44
|
-
| >= 1.
|
45
|
-
| >= 1.
|
44
|
+
| >= 1.15 | 1.4 |
|
45
|
+
| >= 1.16 | 2.0 |
|
46
|
+
| >= 1.18 | 2.2 |
|
47
|
+
| >= 1.21 | 2.3 |
|
46
48
|
|
47
49
|
### Devs
|
48
50
|
|
49
|
-
The callback sends a POST request to /api/v2/hosts/facts with the format you can see [in the API docs](http://theforeman.org/api/1.
|
51
|
+
The callback sends a POST request to /api/v2/hosts/facts with the format you can see [in the API docs](http://theforeman.org/api/1.20/apidoc/v2/hosts/facts.html).
|
50
52
|
|
51
53
|
Facts must contain the output of `ansible -m setup $HOSTNAME`, plus a '_type' and '_timestamp' keys. You can see an example on test/fixtures/sample_facts.json in this repository.
|
52
54
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Api
|
4
|
+
module V2
|
5
|
+
# API controller for Ansible Roles
|
6
|
+
class AnsibleOverrideValuesController < ::Api::V2::BaseController
|
7
|
+
include ::Api::Version2
|
8
|
+
include Foreman::Controller::Parameters::AnsibleOverrideValue
|
9
|
+
|
10
|
+
resource_description do
|
11
|
+
api_version 'v2'
|
12
|
+
api_base_url '/ansible/api'
|
13
|
+
end
|
14
|
+
|
15
|
+
def_param_group :ansible_override_value do
|
16
|
+
param :override_value, Hash, :required => true, :action_aware => true do
|
17
|
+
param :match, String, :required => true, :desc => N_("Override match")
|
18
|
+
param :value, :any_type, :of => LookupKey::KEY_TYPES, :required => false, :desc => N_("Override value, required if omit is false")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
api :POST, "/ansible_override_values/", N_("Create an override value for a specific ansible variable")
|
23
|
+
param :ansible_variable_id, :identifier, :required => true
|
24
|
+
param_group :ansible_override_value, :as => :create
|
25
|
+
|
26
|
+
def create
|
27
|
+
@ansible_variable = AnsibleVariable.authorized(:edit_external_variables).
|
28
|
+
find_by_id(params[:ansible_variable_id].to_i)
|
29
|
+
@override_value = @ansible_variable.lookup_values.create!(lookup_value_params['override_value'])
|
30
|
+
@ansible_variable.update_attribute(:override, true)
|
31
|
+
render 'api/v2/ansible_override_values/show'
|
32
|
+
end
|
33
|
+
|
34
|
+
api :DELETE, "/ansible_override_values/:id", N_("Destroy an override value")
|
35
|
+
param :id, :identifier, :required => true
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
@override_value = LookupValue.find_by_id(params[:id])
|
39
|
+
if @override_value
|
40
|
+
@ansible_variable = AnsibleVariable.where(:id => @override_value.lookup_key_id)
|
41
|
+
@override_value.destroy
|
42
|
+
render 'api/v2/ansible_override_values/show'
|
43
|
+
else
|
44
|
+
not_found
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def resource_name
|
49
|
+
'ansible_variable'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -46,7 +46,8 @@ module Api
|
|
46
46
|
|
47
47
|
api :GET, '/ansible_roles/fetch',
|
48
48
|
N_('Fetch Ansible roles available to be imported')
|
49
|
-
param :proxy_id, :identifier, N_('Smart Proxy to fetch from')
|
49
|
+
param :proxy_id, :identifier, N_('Smart Proxy to fetch from'),
|
50
|
+
:required => true
|
50
51
|
def fetch
|
51
52
|
fetched = []
|
52
53
|
@importer.fetch!.each do |role_name|
|
@@ -5,13 +5,14 @@ module Api
|
|
5
5
|
# API controller for Ansible Variables
|
6
6
|
class AnsibleVariablesController < ::Api::V2::BaseController
|
7
7
|
include ::Api::Version2
|
8
|
+
include Foreman::Controller::Parameters::VariableLookupKey
|
8
9
|
|
9
10
|
resource_description do
|
10
11
|
api_version 'v2'
|
11
12
|
api_base_url '/ansible/api'
|
12
13
|
end
|
13
14
|
|
14
|
-
before_action :find_resource, :only => [:show, :destroy]
|
15
|
+
before_action :find_resource, :only => [:show, :destroy, :update]
|
15
16
|
before_action :find_proxy, :only => [:import, :obsolete]
|
16
17
|
before_action :create_importer, :only => [:import, :obsolete]
|
17
18
|
|
@@ -28,13 +29,40 @@ module Api
|
|
28
29
|
api :DELETE, '/ansible_variables/:id', N_('Deletes Ansible variable')
|
29
30
|
param :id, :identifier, :required => true
|
30
31
|
def destroy
|
31
|
-
|
32
|
+
@ansible_variable.destroy
|
33
|
+
render 'api/v2/ansible_variables/destroy'
|
34
|
+
end
|
35
|
+
|
36
|
+
def_param_group :ansible_variable do
|
37
|
+
param :ansible_variable, Hash, :required => true, :action_aware => true do
|
38
|
+
param :variable, String, :required => true, :desc => N_("Name of variable")
|
39
|
+
param :ansible_role_id, :number, :desc => N_("Role ID")
|
40
|
+
param :default_value, :any_type, :of => LookupKey::KEY_TYPES, :desc => N_("Default value of variable")
|
41
|
+
param :hidden_value, :bool, :desc => N_("When enabled the parameter is hidden in the UI")
|
42
|
+
param :override_value_order, String, :desc => N_("The order in which values are resolved")
|
43
|
+
param :description, String, :desc => N_("Description of variable")
|
44
|
+
param :validator_type, LookupKey::VALIDATOR_TYPES, :desc => N_("Types of validation values")
|
45
|
+
param :validator_rule, String, :desc => N_("Used to enforce certain values for the parameter values")
|
46
|
+
param :variable_type, LookupKey::KEY_TYPES, :desc => N_("Types of variable values")
|
47
|
+
param :merge_overrides, :bool, :desc => N_("Merge all matching values (only array/hash type)")
|
48
|
+
param :merge_default, :bool, :desc => N_("Include default value when merging all matching values")
|
49
|
+
param :avoid_duplicates, :bool, :desc => N_("Remove duplicate values (only array type)")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
api :PUT, '/ansible_variables/:id', N_('Updates Ansible variable')
|
54
|
+
param :id, :identifier, :required => true
|
55
|
+
param_group :ansible_variable, :as => :update
|
56
|
+
|
57
|
+
def update
|
58
|
+
@ansible_variable.update!(variable_lookup_key_params)
|
59
|
+
render 'api/v2/ansible_variables/show'
|
32
60
|
end
|
33
61
|
|
34
62
|
api :PUT, '/ansible_variables/import',
|
35
63
|
N_('Import Ansible variables. This will only import variables '\
|
36
64
|
'for already existing roles, it will not import any new roles')
|
37
|
-
param :proxy_id, :identifier, N_('Smart Proxy to import from')
|
65
|
+
param :proxy_id, :identifier, N_('Smart Proxy to import from'), :required => true
|
38
66
|
def import
|
39
67
|
new_variables = @importer.import_variable_names([])[:new]
|
40
68
|
new_variables.map(&:save)
|
@@ -44,7 +72,7 @@ module Api
|
|
44
72
|
api :PUT, '/ansible_variables/obsolete',
|
45
73
|
N_('Obsolete Ansible variables. This will only obsolete variables '\
|
46
74
|
'for already existing roles, it will not delete any old roles')
|
47
|
-
param :proxy_id, :identifier, N_('Smart Proxy to import from')
|
75
|
+
param :proxy_id, :identifier, N_('Smart Proxy to import from'), :required => true
|
48
76
|
def obsolete
|
49
77
|
old_variables = @importer.import_variable_names([])[:obsolete]
|
50
78
|
old_variables.map(&:destroy)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Foreman
|
4
|
+
module Controller
|
5
|
+
module Parameters
|
6
|
+
# Keys to allow as parameters in the AnsibleVariable controller
|
7
|
+
module AnsibleOverrideValue
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def lookup_value_params_filter
|
12
|
+
Foreman::ParameterFilter.new(::LookupValue).tap do |filter|
|
13
|
+
filter.permit :ansible_variable_id, :override_value => {}
|
14
|
+
|
15
|
+
filter.permit_by_context :hidden_value,
|
16
|
+
:host_or_hostgroup,
|
17
|
+
:lookup_key, :lookup_key_id,
|
18
|
+
:match,
|
19
|
+
:omit,
|
20
|
+
:value,
|
21
|
+
:nested => true
|
22
|
+
|
23
|
+
filter.permit_by_context :id,
|
24
|
+
:_destroy,
|
25
|
+
:ui => false, :api => false, :nested => true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def lookup_value_params
|
31
|
+
self.class.lookup_value_params_filter.filter_params(params, parameter_filter_context)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -4,51 +4,70 @@ require 'ipaddress'
|
|
4
4
|
module ForemanAnsible
|
5
5
|
# Relations to make Host::Managed 'have' ansible roles
|
6
6
|
module HostManagedExtensions
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
include ::ForemanAnsible::Concerns::JobInvocationHelper
|
9
|
-
|
10
7
|
# rubocop:disable Metrics/BlockLength
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:dependent => :destroy
|
15
|
-
scoped_search :relation => :ansible_roles, :on => :name,
|
16
|
-
:complete_value => true, :rename => :role,
|
17
|
-
:only_explicit => true
|
8
|
+
def self.prepended(base)
|
9
|
+
base.instance_eval do
|
10
|
+
include ::ForemanAnsible::Concerns::JobInvocationHelper
|
18
11
|
|
19
|
-
|
20
|
-
|
12
|
+
has_many :host_ansible_roles, :foreign_key => :host_id
|
13
|
+
has_many :ansible_roles, :through => :host_ansible_roles,
|
14
|
+
:dependent => :destroy
|
15
|
+
scoped_search :relation => :ansible_roles, :on => :name,
|
16
|
+
:complete_value => true, :rename => :role,
|
17
|
+
:only_explicit => true
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
hostgroup.inherited_and_own_ansible_roles
|
19
|
+
before_provision :play_ansible_roles
|
20
|
+
audit_associations :ansible_roles
|
25
21
|
end
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
23
|
+
base.singleton_class.prepend ClassMethods
|
24
|
+
end
|
25
|
+
|
26
|
+
def inherited_ansible_roles
|
27
|
+
return [] unless hostgroup
|
28
|
+
hostgroup.inherited_and_own_ansible_roles
|
29
|
+
end
|
30
|
+
|
31
|
+
# This one should be fixed, disabled for the moment as we're
|
32
|
+
# in a rush to get the release out
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
34
|
+
def play_ansible_roles
|
35
|
+
return true unless ansible_roles.present? ||
|
36
|
+
inherited_ansible_roles.present?
|
37
|
+
composer = job_composer(:ansible_run_host, self)
|
38
|
+
composer.triggering.mode = :future
|
39
|
+
composer.triggering.start_at = (
|
40
|
+
Time.zone.now +
|
41
|
+
Setting::Ansible[:ansible_post_provision_timeout].to_i.seconds
|
42
|
+
)
|
43
|
+
composer.trigger!
|
44
|
+
logger.info("Task for Ansible roles on #{self} before_provision: "\
|
45
|
+
"#{job_invocation_path(composer.job_invocation)}")
|
46
|
+
rescue Foreman::Exception => e
|
47
|
+
logger.info("Error running Ansible roles on #{self} before_provision: "\
|
48
|
+
"#{e.message}")
|
49
|
+
end
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
51
|
+
|
52
|
+
def all_ansible_roles
|
53
|
+
(ansible_roles + inherited_ansible_roles).uniq
|
54
|
+
end
|
47
55
|
|
48
|
-
|
49
|
-
|
56
|
+
def host_params_hash
|
57
|
+
values = AnsibleVariable.where(:ansible_role_id => all_ansible_roles.pluck(:id)).
|
58
|
+
values_hash(self).raw.values
|
59
|
+
transformed = values.each_with_object({}) do |item, memo|
|
60
|
+
item.map do |name, hash|
|
61
|
+
variable = AnsibleVariable.find_by :key => name
|
62
|
+
safe_value = variable.hidden_value? ? variable.safe_value : hash[:value]
|
63
|
+
memo[name] = { :value => hash[:value], :safe_value => safe_value, :source => 'global' }
|
64
|
+
end
|
65
|
+
memo
|
50
66
|
end
|
67
|
+
|
68
|
+
super.merge transformed
|
51
69
|
end
|
70
|
+
|
52
71
|
# rubocop:enable Metrics/BlockLength
|
53
72
|
# Class methods we may need to override or add
|
54
73
|
module ClassMethods
|
@@ -19,9 +19,7 @@ module ForemanAnsible
|
|
19
19
|
# more advanced cases). Therefore we have only the 'all' group
|
20
20
|
# with all hosts.
|
21
21
|
def to_hash
|
22
|
-
hosts = @hosts.map
|
23
|
-
RemoteExecutionProvider.find_ip_or_hostname(h)
|
24
|
-
end
|
22
|
+
hosts = @hosts.map(&:name)
|
25
23
|
|
26
24
|
{ 'all' => { 'hosts' => hosts,
|
27
25
|
'vars' => template_inputs(@template_invocation) },
|
@@ -31,7 +29,7 @@ module ForemanAnsible
|
|
31
29
|
def hosts_vars
|
32
30
|
hosts.reduce({}) do |hash, host|
|
33
31
|
hash.update(
|
34
|
-
|
32
|
+
host.name => host_vars(host)
|
35
33
|
)
|
36
34
|
end
|
37
35
|
end
|
@@ -94,8 +92,10 @@ module ForemanAnsible
|
|
94
92
|
'ansible_become_user' => @template_invocation.effective_user,
|
95
93
|
'ansible_user' => host_setting(host, 'remote_execution_ssh_user'),
|
96
94
|
'ansible_ssh_pass' => rex_ssh_password(host),
|
95
|
+
'ansible_sudo_pass' => rex_sudo_password(host),
|
97
96
|
'ansible_ssh_private_key_file' => ansible_or_rex_ssh_private_key(host),
|
98
|
-
'ansible_port' => host_setting(host, 'remote_execution_ssh_port')
|
97
|
+
'ansible_port' => host_setting(host, 'remote_execution_ssh_port'),
|
98
|
+
'ansible_host' => AnsibleProvider.find_ip_or_hostname(host)
|
99
99
|
}
|
100
100
|
params['ansible_become'] = true if params['ansible_become_user'].present?
|
101
101
|
# Backward compatibility for Ansible 1.x
|
@@ -117,6 +117,11 @@ module ForemanAnsible
|
|
117
117
|
host_setting(host, 'remote_execution_ssh_password')
|
118
118
|
end
|
119
119
|
|
120
|
+
def rex_sudo_password(host)
|
121
|
+
@template_invocation.job_invocation.sudo_password ||
|
122
|
+
host_setting(host, 'remote_execution_sudo_password')
|
123
|
+
end
|
124
|
+
|
120
125
|
def ansible_or_rex_ssh_private_key(host)
|
121
126
|
ansible_private_file = host_setting(host, 'ansible_ssh_private_key_file')
|
122
127
|
if !ansible_private_file.empty?
|
@@ -5,6 +5,7 @@ module ForemanAnsible
|
|
5
5
|
module OperatingSystemParser
|
6
6
|
def operatingsystem
|
7
7
|
args = { :name => os_name, :major => os_major, :minor => os_minor }
|
8
|
+
args[:release_name] = os_release_name if os_name == 'Debian'
|
8
9
|
return @local_os if local_os(args).present?
|
9
10
|
return @new_os if new_os(args).present?
|
10
11
|
logger.debug do
|
@@ -39,6 +40,15 @@ module ForemanAnsible
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
def deb_release_map
|
44
|
+
{ '7' => 'wheezy', '8' => 'jessie', '9' => 'stretch', '10' => 'buster' }
|
45
|
+
end
|
46
|
+
|
47
|
+
def os_release_name
|
48
|
+
return '' unless os_name == 'Debian'
|
49
|
+
deb_release_map[debian_os_major_sid]
|
50
|
+
end
|
51
|
+
|
42
52
|
# rubocop:disable AbcSize, CyclomaticComplexity, PerceivedComplexity
|
43
53
|
def os_major
|
44
54
|
if os_name == 'Debian' &&
|
@@ -26,7 +26,7 @@
|
|
26
26
|
variable.ansible_role.name,
|
27
27
|
hash_for_ansible_variables_path(:search => "ansible_role = #{variable.ansible_role}")
|
28
28
|
) %></td>
|
29
|
-
<td class="ellipsis"><%=
|
29
|
+
<td class="ellipsis"><%= variable.key_type || 'string' %></td>
|
30
30
|
<td class="ellipsis">
|
31
31
|
<% links = [
|
32
32
|
display_delete_if_authorized(
|
@@ -1,10 +1,11 @@
|
|
1
1
|
object @ansible_variable
|
2
2
|
|
3
3
|
attribute :parameter
|
4
|
-
attributes :id, :ansible_role, :
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:override_value_order, :created_at, :updated_at
|
4
|
+
attributes :id, :variable, :ansible_role, :ansible_role_id, :description, :override,
|
5
|
+
:variable_type, :hidden_value?, :validator_type,
|
6
|
+
:validator_rule, :merge_overrides, :merge_default,
|
7
|
+
:avoid_duplicates, :override_value_order, :created_at, :updated_at,
|
8
|
+
:default_value
|
8
9
|
|
9
10
|
node do |ansible_variable|
|
10
11
|
{
|
data/config/routes.rb
CHANGED
@@ -79,12 +79,14 @@ Rails.application.routes.draw do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
resources :ansible_variables, :only => [:show, :index, :destroy] do
|
82
|
+
resources :ansible_variables, :only => [:show, :index, :destroy, :update] do
|
83
83
|
collection do
|
84
84
|
put :import
|
85
85
|
put :obsolete
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
resources :ansible_override_values, :only => [:create, :destroy]
|
88
90
|
end
|
89
91
|
end
|
90
92
|
end
|