foreman_ansible 1.0 → 1.1
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/Rakefile +6 -27
- data/app/controllers/ansible_roles_controller.rb +55 -0
- data/app/controllers/api/v2/ansible_roles_controller.rb +52 -0
- data/app/controllers/foreman_ansible/concerns/hosts_controller_extensions.rb +11 -10
- data/app/helpers/foreman_ansible/ansible_plugin_helper.rb +8 -0
- data/app/helpers/foreman_ansible/ansible_reports_helper.rb +6 -4
- data/app/helpers/foreman_ansible/ansible_roles_helper.rb +17 -3
- data/app/helpers/foreman_ansible/hosts_helper_extensions.rb +4 -3
- data/app/lib/actions/foreman_ansible/play_host_roles.rb +56 -0
- data/app/lib/actions/foreman_ansible/play_hosts_roles.rb +26 -0
- data/app/lib/proxy_api/ansible.rb +28 -0
- data/app/models/ansible_role.rb +8 -0
- data/app/models/concerns/foreman_ansible/has_many_ansible_roles.rb +13 -0
- data/app/models/concerns/foreman_ansible/host_managed_extensions.rb +5 -1
- data/app/models/concerns/foreman_ansible/hostgroup_extensions.rb +19 -0
- data/app/models/host_ansible_role.rb +0 -2
- data/app/models/hostgroup_ansible_role.rb +8 -0
- data/app/overrides/ansible_roles_tab.rb +2 -2
- data/app/overrides/hostgroup_ansible_roles_tab.rb +14 -0
- data/app/services/foreman_ansible/api_roles_importer.rb +16 -0
- data/app/services/foreman_ansible/fact_importer.rb +2 -1
- data/app/services/foreman_ansible/inventory_creator.rb +37 -5
- data/app/services/foreman_ansible/playbook_creator.rb +3 -4
- data/app/services/foreman_ansible/proxy_selector.rb +19 -0
- data/app/services/foreman_ansible/roles_importer.rb +42 -15
- data/app/services/foreman_ansible/ui_roles_importer.rb +26 -0
- data/app/views/ansible_roles/import.html.erb +51 -0
- data/app/views/ansible_roles/index.html.erb +30 -0
- data/app/views/ansible_roles/welcome.html.erb +14 -0
- data/app/views/api/v2/ansible_roles/import.json.rabl +3 -0
- data/app/views/api/v2/ansible_roles/index.json.rabl +3 -0
- data/app/views/api/v2/ansible_roles/obsolete.json.rabl +3 -0
- data/app/views/api/v2/ansible_roles/show.json.rabl +3 -0
- data/app/views/foreman_ansible/ansible_roles/_select_tab_content.html.erb +6 -0
- data/app/views/foreman_ansible/{hosts/_tab_title.html.erb → ansible_roles/_select_tab_title.html.erb} +0 -0
- data/config/routes.rb +25 -2
- data/db/migrate/20160705082036_create_ansible_role.rb +2 -1
- data/db/migrate/20160706074540_create_join_table_hosts_ansible_roles.rb +1 -0
- data/db/migrate/20160707195442_create_host_ansible_roles.rb +1 -0
- data/db/migrate/20160729094457_add_columns_to_ansible_role.rb +12 -0
- data/db/migrate/20160802153302_create_join_table_hostgroup_ansible_roles.rb +10 -0
- data/db/migrate/20160805094233_add_primary_key_hostgroup_ansible_roles.rb +6 -0
- data/db/seeds.d/{62-ansible_proxy_feature.rb → 62_ansible_proxy_feature.rb} +0 -0
- data/lib/foreman_ansible.rb +1 -0
- data/lib/foreman_ansible/engine.rb +54 -4
- data/lib/foreman_ansible/version.rb +1 -1
- data/locale/en/foreman_ansible.po +139 -2
- data/locale/foreman_ansible.pot +200 -8
- data/test/factories/ansible_proxy.rb +7 -0
- data/test/factories/ansible_roles.rb +2 -2
- data/test/fixtures/ansible_permissions.yml +11 -0
- data/test/functional/ansible_roles_controller_test.rb +16 -0
- data/test/functional/api/v2/ansible_roles_controller_test.rb +24 -0
- data/test/functional/hosts_controller_test.rb +65 -24
- data/test/support/fixture_support.rb +25 -0
- data/test/support/foreman_tasks/task.rb +47 -0
- data/test/support/foreman_test_helper_additions.rb +22 -0
- data/test/test_plugin_helper.rb +5 -2
- data/test/unit/ansible_role_test.rb +6 -2
- data/test/unit/concerns/host_managed_extensions_test.rb +37 -0
- data/test/unit/concerns/hostgroup_extensions_test.rb +36 -0
- data/test/unit/fact_importer_test.rb +11 -8
- data/test/unit/fact_parser_test.rb +2 -0
- data/test/unit/fact_sparser_test.rb +1 -0
- data/test/unit/helpers/foreman_ansible/ansible_reports_helper_test.rb +1 -0
- data/test/unit/host_ansible_role_test.rb +10 -0
- data/test/unit/hostgroup_ansible_role_test.rb +19 -0
- data/test/unit/lib/foreman_ansible_core/playbook_runner_test.rb +28 -0
- data/test/unit/lib/proxy_api/ansible_test.rb +23 -0
- data/test/unit/services/api_roles_importer_test.rb +28 -0
- data/test/unit/services/proxy_selector_test.rb +28 -0
- data/test/unit/services/roles_importer_test.rb +17 -0
- data/test/unit/services/ui_roles_importer_test.rb +30 -0
- metadata +108 -14
- data/app/jobs/foreman_ansible/run_playbook_job.rb +0 -28
- data/app/services/foreman_ansible/role_player.rb +0 -26
- data/app/views/foreman_ansible/hosts/_tab_content.html.erb +0 -4
- data/lib/tasks/foreman_ansible_tasks.rake +0 -40
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7394d81e94f7dd6bfda57b0a539adc09a1c068e0
|
|
4
|
+
data.tar.gz: 87475c40db6d3a594517de1443878ffe107b85f6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 48d0c08d791d3543d6cbf2341c6a3ed66ba9c0d4b9a8c9e5bbcc0344444ef9c8c94db91ae4b7bf193ef915c75d9162470877140c46cd9d3c44e110d3593d809b
|
|
7
|
+
data.tar.gz: 79df637cc5ce51f5f6d9ee40ae0587b18c4dc9f339ae0edd4d813dd97fcfe1965bc589d7c176fcabcbd202cd47d75a839695ed652a9636ff32e37175164e168b
|
data/Rakefile
CHANGED
|
@@ -4,37 +4,16 @@ begin
|
|
|
4
4
|
rescue LoadError
|
|
5
5
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
6
6
|
end
|
|
7
|
-
begin
|
|
8
|
-
require 'rdoc/task'
|
|
9
|
-
rescue LoadError
|
|
10
|
-
require 'rdoc/rdoc'
|
|
11
|
-
require 'rake/rdoctask'
|
|
12
|
-
RDoc::Task = Rake::RDocTask
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
17
|
-
rdoc.title = 'ForemanAnsible'
|
|
18
|
-
rdoc.options << '--line-numbers'
|
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
APP_RAKEFILE = File.expand_path('../test/dummy/Rakefile', __FILE__)
|
|
24
|
-
|
|
25
|
-
Bundler::GemHelper.install_tasks
|
|
26
7
|
|
|
27
8
|
require 'rake/testtask'
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
9
|
+
Rake::TestTask.new("test:core") do |test|
|
|
10
|
+
test_dir = File.join(File.dirname(__FILE__), 'test/lib')
|
|
11
|
+
test.pattern = "#{test_dir}/**/*_test.rb"
|
|
12
|
+
test.libs << test_dir
|
|
13
|
+
test.verbose = false
|
|
14
|
+
test.warning = false
|
|
34
15
|
end
|
|
35
16
|
|
|
36
|
-
task :default => :test
|
|
37
|
-
|
|
38
17
|
begin
|
|
39
18
|
require 'rubocop/rake_task'
|
|
40
19
|
RuboCop::RakeTask.new
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# UI controller for ansible roles
|
|
2
|
+
class AnsibleRolesController < ::ApplicationController
|
|
3
|
+
include Foreman::Controller::AutoCompleteSearch
|
|
4
|
+
|
|
5
|
+
before_action :find_resource, :only => [:destroy]
|
|
6
|
+
before_action :find_proxy, :only => [:import]
|
|
7
|
+
before_action :create_importer, :only => [:import, :confirm_import]
|
|
8
|
+
|
|
9
|
+
def index
|
|
10
|
+
@ansible_roles = resource_base.search_for(params[:search],
|
|
11
|
+
:order => params[:order]).
|
|
12
|
+
paginate(:page => params[:page],
|
|
13
|
+
:per_page => params[:per_page])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def destroy
|
|
17
|
+
if @ansible_role.destroy
|
|
18
|
+
process_success
|
|
19
|
+
else
|
|
20
|
+
process_error
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def import
|
|
25
|
+
changed = @importer.import!
|
|
26
|
+
if changed.values.all?(&:empty?)
|
|
27
|
+
notice no_changed_roles_message
|
|
28
|
+
redirect_to ansible_roles_path
|
|
29
|
+
else
|
|
30
|
+
render :locals => { :changed => changed }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def confirm_import
|
|
35
|
+
@importer.finish_import(params[:changed])
|
|
36
|
+
notice _('Import of roles successfully finished.')
|
|
37
|
+
redirect_to ansible_roles_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def find_proxy
|
|
43
|
+
return nil unless params[:proxy]
|
|
44
|
+
@proxy = SmartProxy.authorized(:view_smart_proxies).find(params[:proxy])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_importer
|
|
48
|
+
@importer = ForemanAnsible::UiRolesImporter.new(@proxy)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def no_changed_roles_message
|
|
52
|
+
return _('No changes in roles detected.') unless @proxy.present?
|
|
53
|
+
_('No changes in roles detected on %s.') % @proxy.name
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Api
|
|
2
|
+
module V2
|
|
3
|
+
# API controller for Ansible Roles
|
|
4
|
+
class AnsibleRolesController < ::Api::V2::BaseController
|
|
5
|
+
include ::Api::Version2
|
|
6
|
+
|
|
7
|
+
before_action :find_resource, :only => [:show, :destroy]
|
|
8
|
+
before_action :find_proxy, :only => [:import, :obsolete]
|
|
9
|
+
before_action :create_importer, :only => [:import, :obsolete]
|
|
10
|
+
|
|
11
|
+
api :GET, '/ansible/ansible_roles/:id', N_('Show role')
|
|
12
|
+
param :id, :identifier, :required => true
|
|
13
|
+
def show
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
api :GET, '/ansible/ansible_roles', N_('List Ansible roles')
|
|
17
|
+
param_group :search_and_pagination, ::Api::V2::BaseController
|
|
18
|
+
def index
|
|
19
|
+
@ansible_roles = resource_scope_for_index
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
api :DELETE, '/ansible/ansible_roles/:id', N_('Deletes Ansible role')
|
|
23
|
+
param :id, :identifier, :required => true
|
|
24
|
+
def destroy
|
|
25
|
+
process_response @ansible_role.destroy
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
api :POST, '/ansible/ansible_roles/import', N_('Import Ansible roles')
|
|
29
|
+
param :proxy, Hash, N_('Smart Proxy to import from')
|
|
30
|
+
def import
|
|
31
|
+
@imported = @importer.import!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
api :POST, '/ansible/ansible_roles/obsolete', N_('Obsolete Ansible roles')
|
|
35
|
+
param :proxy, Hash, N_('Smart Proxy to import from')
|
|
36
|
+
def obsolete
|
|
37
|
+
@obsoleted = @importer.obsolete!
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def find_proxy
|
|
43
|
+
return nil unless params[:proxy]
|
|
44
|
+
@proxy = SmartProxy.authorized(:view_smart_proxies).find(params[:proxy])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_importer
|
|
48
|
+
@importer = ForemanAnsible::ApiRolesImporter.new(@proxy)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -3,23 +3,24 @@ module ForemanAnsible
|
|
|
3
3
|
# Extra methods to enforce Ansible roles on a host or multiple hosts
|
|
4
4
|
module HostsControllerExtensions
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
|
+
include ForemanTasks::Triggers
|
|
6
7
|
|
|
7
8
|
def play_roles
|
|
8
9
|
find_resource
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
task = async_task(::Actions::ForemanAnsible::PlayHostRoles, @host)
|
|
11
|
+
redirect_to task
|
|
12
|
+
rescue Foreman::Exception => e
|
|
13
|
+
error e.message
|
|
14
|
+
redirect_to host_path(@host)
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def multiple_play_roles
|
|
16
18
|
find_multiple
|
|
17
|
-
@hosts
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
redirect_to :hosts
|
|
19
|
+
task = async_task(::Actions::ForemanAnsible::PlayHostsRoles, @hosts)
|
|
20
|
+
redirect_to task
|
|
21
|
+
rescue Foreman::Exception => e
|
|
22
|
+
error e.message
|
|
23
|
+
redirect_to hosts_path
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
private
|
|
@@ -12,10 +12,12 @@ module ForemanAnsible
|
|
|
12
12
|
|
|
13
13
|
def ansible_module_message(log)
|
|
14
14
|
paragraph_style = 'margin:0px;font-family:Menlo,Monaco,Consolas,monospace'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
safe_join(
|
|
16
|
+
JSON.parse(log.message.value).except('invocation').map do |name, value|
|
|
17
|
+
next if value.blank?
|
|
18
|
+
content_tag(:p, "#{name}: #{value}", :style => paragraph_style)
|
|
19
|
+
end
|
|
20
|
+
)
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def ansible_report?(log)
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
module ForemanAnsible
|
|
2
2
|
# Small convenience to list all roles in the UI
|
|
3
3
|
module AnsibleRolesHelper
|
|
4
|
-
def
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
def ansible_proxy_links(hash, classes = nil)
|
|
5
|
+
links = SmartProxy.with_features('Ansible').map do |proxy|
|
|
6
|
+
display_link_if_authorized(_('Import from %s') % proxy.name,
|
|
7
|
+
hash.merge(:proxy => proxy),
|
|
8
|
+
:class => classes)
|
|
9
|
+
end.flatten
|
|
10
|
+
links.unshift display_link_if_authorized(_('Import from Foreman host'),
|
|
11
|
+
hash,
|
|
12
|
+
:class => classes)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ansible_proxy_import(hash)
|
|
16
|
+
select_action_button(_('Import'), {}, ansible_proxy_links(hash))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def import_time(role)
|
|
20
|
+
_('%s ago') % time_ago_in_words(role.updated_at)
|
|
7
21
|
end
|
|
8
22
|
end
|
|
9
23
|
end
|
|
@@ -11,9 +11,10 @@ module ForemanAnsible
|
|
|
11
11
|
def host_title_actions_with_run_ansible_roles(*args)
|
|
12
12
|
button = link_to(
|
|
13
13
|
icon_text('play', ' ' + _('Ansible roles'), :kind => 'fa'),
|
|
14
|
-
|
|
14
|
+
play_roles_host_path(:id => args.first.id),
|
|
15
15
|
:id => :ansible_roles_button,
|
|
16
|
-
:class => 'btn btn-default'
|
|
16
|
+
:class => 'btn btn-default'
|
|
17
|
+
)
|
|
17
18
|
title_actions(button_group(button)) if args.first.ansible_roles.present?
|
|
18
19
|
host_title_actions_without_run_ansible_roles(*args)
|
|
19
20
|
end
|
|
@@ -21,7 +22,7 @@ module ForemanAnsible
|
|
|
21
22
|
def multiple_actions_with_run_ansible_roles
|
|
22
23
|
multiple_actions_without_run_ansible_roles +
|
|
23
24
|
[[_('Play Ansible roles'),
|
|
24
|
-
|
|
25
|
+
multiple_play_roles_hosts_path,
|
|
25
26
|
false]]
|
|
26
27
|
end
|
|
27
28
|
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Actions
|
|
2
|
+
module ForemanAnsible
|
|
3
|
+
# Actions that initiaztes the playbook run for roles assigned to
|
|
4
|
+
# the host. It doest that either locally or via a proxy when available.
|
|
5
|
+
class PlayHostRoles < Actions::EntryAction
|
|
6
|
+
include ::Actions::Helpers::WithContinuousOutput
|
|
7
|
+
include ::Actions::Helpers::WithDelegatedAction
|
|
8
|
+
|
|
9
|
+
def plan(host, proxy_selector = ::ForemanAnsible::ProxySelector.new)
|
|
10
|
+
input[:host] = { :id => host.id, :name => host.fqdn }
|
|
11
|
+
proxy = proxy_selector.determine_proxy(host)
|
|
12
|
+
inventory_creator = ::ForemanAnsible::InventoryCreator.new([host])
|
|
13
|
+
role_names = host.all_ansible_roles.map(&:name)
|
|
14
|
+
playbook_creator = ::ForemanAnsible::PlaybookCreator.new(role_names)
|
|
15
|
+
plan_delegated_action(proxy, ::ForemanAnsibleCore::Actions::RunPlaybook,
|
|
16
|
+
:inventory => inventory_creator.to_hash.to_json,
|
|
17
|
+
:playbook => playbook_creator.roles_playbook)
|
|
18
|
+
plan_self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def finalize
|
|
22
|
+
if delegated_output[:exit_status].to_s != '0'
|
|
23
|
+
error! _('Playbook execution failed')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def rescue_strategy
|
|
28
|
+
::Dynflow::Action::Rescue::Fail
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def humanized_input
|
|
32
|
+
_('on host %{name}') % { :name => input.fetch(:host, {})[:name] }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def humanized_name
|
|
36
|
+
_('Play Ansible roles')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def humanized_output
|
|
40
|
+
continuous_output.humanize
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def continuous_output_providers
|
|
44
|
+
super << self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def fill_continuous_output(continuous_output)
|
|
48
|
+
delegated_output.fetch('result', []).each do |raw_output|
|
|
49
|
+
continuous_output.add_raw_output(raw_output)
|
|
50
|
+
end
|
|
51
|
+
rescue => e
|
|
52
|
+
continuous_output.add_exception(_('Error loading data from proxy'), e)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Actions
|
|
2
|
+
module ForemanAnsible
|
|
3
|
+
# Bulk action for running ansible roles
|
|
4
|
+
class PlayHostsRoles < Actions::ActionWithSubPlans
|
|
5
|
+
def plan(hosts)
|
|
6
|
+
plan_self(:host_ids => hosts.map(&:id))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def create_sub_plans
|
|
10
|
+
proxy_selector = ::ForemanAnsible::ProxySelector.new
|
|
11
|
+
input[:host_ids].map do |host_id|
|
|
12
|
+
host = Host.find(host_id)
|
|
13
|
+
trigger(PlayHostRoles, host, proxy_selector)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rescue_strategy
|
|
18
|
+
::Dynflow::Action::Rescue::Fail
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def humanized_name
|
|
22
|
+
_('Bulk play Ansible roles')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module ProxyAPI
|
|
2
|
+
# ProxyAPI for Ansible
|
|
3
|
+
class Ansible < ::ProxyAPI::Resource
|
|
4
|
+
def initialize(args)
|
|
5
|
+
@url = args[:url] + '/ansible/'
|
|
6
|
+
super args
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
PROXY_ERRORS = [
|
|
10
|
+
Errno::ECONNREFUSED,
|
|
11
|
+
SocketError,
|
|
12
|
+
Timeout::Error,
|
|
13
|
+
Errno::EINVAL,
|
|
14
|
+
Errno::ECONNRESET,
|
|
15
|
+
EOFError,
|
|
16
|
+
Net::HTTPBadResponse,
|
|
17
|
+
Net::HTTPHeaderSyntaxError,
|
|
18
|
+
Net::ProtocolError,
|
|
19
|
+
RestClient::ResourceNotFound
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
22
|
+
def roles
|
|
23
|
+
parse(get('roles'))
|
|
24
|
+
rescue *PROXY_ERRORS => e
|
|
25
|
+
raise ProxyException.new(url, e, N_('Unable to get roles from Ansible'))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/app/models/ansible_role.rb
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Simple model to store basic info about the Ansible role
|
|
2
2
|
class AnsibleRole < ActiveRecord::Base
|
|
3
|
+
include Authorizable
|
|
4
|
+
|
|
5
|
+
self.include_root_in_json = false
|
|
3
6
|
validates :name, :presence => true, :uniqueness => true
|
|
4
7
|
has_many :host_ansible_roles
|
|
5
8
|
has_many_hosts :through => :host_ansible_roles, :dependent => :destroy
|
|
9
|
+
has_many :hostgroup_ansible_roles
|
|
10
|
+
has_many :hostgroups, :through => :hostgroup_ansible_roles,
|
|
11
|
+
:dependent => :destroy
|
|
12
|
+
|
|
13
|
+
scoped_search :on => :name, :complete_value => true
|
|
6
14
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ForemanAnsible
|
|
2
|
+
# Define common behaviors between models that have many Ansible roles,
|
|
3
|
+
# currently Host and Hostgroup. Takes care of inheritance, etc...
|
|
4
|
+
module HasManyAnsibleRoles
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
def all_ansible_roles
|
|
9
|
+
(ansible_roles + inherited_ansible_roles).uniq
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -7,8 +7,12 @@ module ForemanAnsible
|
|
|
7
7
|
has_many :host_ansible_roles, :foreign_key => :host_id
|
|
8
8
|
has_many :ansible_roles, :through => :host_ansible_roles,
|
|
9
9
|
:dependent => :destroy
|
|
10
|
+
include ForemanAnsible::HasManyAnsibleRoles
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
def inherited_ansible_roles
|
|
13
|
+
return [] unless hostgroup
|
|
14
|
+
hostgroup.all_ansible_roles
|
|
15
|
+
end
|
|
12
16
|
end
|
|
13
17
|
end
|
|
14
18
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module ForemanAnsible
|
|
2
|
+
# Relations to make Hostgroup 'have' ansible roles
|
|
3
|
+
module HostgroupExtensions
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
has_many :hostgroup_ansible_roles, :foreign_key => :hostgroup_id
|
|
8
|
+
has_many :ansible_roles, :through => :hostgroup_ansible_roles,
|
|
9
|
+
:dependent => :destroy
|
|
10
|
+
include ForemanAnsible::HasManyAnsibleRoles
|
|
11
|
+
|
|
12
|
+
def inherited_ansible_roles
|
|
13
|
+
ancestors.reduce([]) do |roles, hostgroup|
|
|
14
|
+
roles + hostgroup.ansible_roles
|
|
15
|
+
end.uniq
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|