foreman_chef 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -5
- data/app/helpers/foreman_chef/chef_proxy_form.rb +14 -0
- data/app/lib/actions/foreman_chef/client/destroy.rb +33 -0
- data/app/lib/actions/foreman_chef/host/destroy.rb +43 -0
- data/app/lib/proxy_api/foreman_chef/chef_proxy.rb +53 -0
- data/app/models/foreman_chef/chef_proxy_association.rb +10 -0
- data/app/models/foreman_chef/concerns/host_action_subject.rb +19 -0
- data/app/models/foreman_chef/fact_importer.rb +4 -0
- data/app/models/foreman_chef/host_extensions.rb +16 -0
- data/app/models/foreman_chef/hostgroup_extensions.rb +18 -0
- data/app/models/foreman_chef/smart_proxy_extensions.rb +38 -0
- data/app/models/setting/foreman_chef.rb +17 -0
- data/app/overrides/add_chef_proxy.rb +16 -0
- data/db/migrate/20140220145827_add_chef_proxy_id_to_host.rb +5 -0
- data/db/migrate/20140513144804_add_chef_proxy_id_to_hostgroup.rb +5 -0
- data/db/seeds.rb +1 -0
- data/lib/foreman_chef/engine.rb +32 -6
- data/lib/foreman_chef/version.rb +1 -1
- metadata +44 -4
- data/test/dummy/log/development.log +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48b50dcd6355797ece89dee99d3f9ebef0d347e4
|
4
|
+
data.tar.gz: 79ae27dc6b1c7d23b6d7d2acc942b3f6a94aea2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 894eca488c8631c39043510f530404c0f3cc1ea6bee1854cd41b7d0a214ac5d04fc08754390727b23cc01aa27b539625a45be881946a12b969b431ad953ad1f7
|
7
|
+
data.tar.gz: 3d2920bec28fe08a6c7bbb39ee6e61a779c35d31cdf4c0f9e740515fb940a674ae055491b65aeb5441b6af8ead9990b969f69c0213b29b05b3cfaee02d548aec
|
data/README.md
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# ForemanChef
|
2
2
|
|
3
|
-
This plugin adds a Chef fact
|
3
|
+
This plugin adds a Chef fact importer to Foreman. It basically means that when you setup your chef
|
4
4
|
clients to use foreman handlers (https://github.com/theforeman/chef-handler-foreman) and install
|
5
5
|
this plugin you receive nested facts from chef-client.
|
6
6
|
|
7
7
|
This plugin expects foreman to support nested facts which is was added in 1.4.
|
8
|
-
To install this plugin you just have to add this line to your
|
8
|
+
To install this plugin you just have to add this line to your Gemfile.
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
gem 'foreman_chef'
|
11
|
+
gem 'foreman_chef'
|
12
12
|
```
|
13
13
|
|
14
|
-
and run bundle install
|
14
|
+
and run ```bundle install```. Don't forget to restart foreman after this change.
|
15
15
|
|
16
16
|
If you want to use this in production I recommend to combine this plugin with foreman-background
|
17
17
|
(https://github.com/ohadlevy/foreman-background) which runs report and facts import as a background
|
@@ -19,4 +19,10 @@ tasks.
|
|
19
19
|
|
20
20
|
## License
|
21
21
|
|
22
|
-
|
22
|
+
Copyright (c) 2013-2014 Marek Hulán
|
23
|
+
|
24
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
25
|
+
|
26
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
27
|
+
|
28
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
module ChefProxyForm
|
3
|
+
def chef_proxy_form(f)
|
4
|
+
# Don't show this if we have no Chef proxies, otherwise always include blank
|
5
|
+
# so the user can choose not to use puppet on this host
|
6
|
+
proxies = SmartProxy.with_taxonomy_scope_override(@location,@organization).with_features('Chef')
|
7
|
+
return if proxies.count == 0
|
8
|
+
select_f f, :chef_proxy_id, proxies, :id, :name,
|
9
|
+
{ :include_blank => blank_or_inherit_f(f, :chef_proxy) },
|
10
|
+
{ :label => _("Chef proxy"),
|
11
|
+
:help_inline => _("Use this foreman proxy as an entry point to your Chef, node will be managed via this proxy") }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Actions
|
2
|
+
module ForemanChef
|
3
|
+
module Client
|
4
|
+
class Destroy < Actions::EntryAction
|
5
|
+
|
6
|
+
def plan(fqdn, proxy)
|
7
|
+
if ::Setting::ForemanChef.auto_deletion
|
8
|
+
client_exists_in_chef = proxy.show_client(fqdn)
|
9
|
+
if client_exists_in_chef
|
10
|
+
plan_self :chef_proxy_id => proxy.id, :fqdn => fqdn
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
proxy = ::SmartProxy.find_by_id(input[:chef_proxy_id])
|
17
|
+
action_logger.debug "Deleting client #{input[:fqdn]} on proxy #{proxy.name} at #{proxy.url}"
|
18
|
+
self.output = proxy.delete_client(input[:fqdn])
|
19
|
+
end
|
20
|
+
|
21
|
+
def humanized_name
|
22
|
+
_("Delete client")
|
23
|
+
end
|
24
|
+
|
25
|
+
def humanized_input
|
26
|
+
input[:fqdn]
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Actions
|
2
|
+
module ForemanChef
|
3
|
+
module Host
|
4
|
+
class Destroy < Actions::EntryAction
|
5
|
+
|
6
|
+
def plan(host)
|
7
|
+
action_subject(host)
|
8
|
+
if (::Setting::ForemanChef.auto_deletion && proxy = ::SmartProxy.find_by_id(host.chef_proxy_id))
|
9
|
+
node_exists_in_chef = proxy.show_node(host.name)
|
10
|
+
if node_exists_in_chef
|
11
|
+
plan_self :chef_proxy_id => host.chef_proxy_id
|
12
|
+
end
|
13
|
+
|
14
|
+
plan_action Actions::ForemanChef::Client::Destroy, host.name, proxy
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
proxy = ::SmartProxy.find_by_id(input[:chef_proxy_id])
|
20
|
+
action_logger.debug "Deleting #{input[:host][:name]} on proxy #{proxy.name} at #{proxy.url}"
|
21
|
+
self.output = proxy.delete_node(input[:host][:name])
|
22
|
+
end
|
23
|
+
|
24
|
+
def humanized_name
|
25
|
+
_("Delete host")
|
26
|
+
end
|
27
|
+
|
28
|
+
def humanized_input
|
29
|
+
input[:host] && input[:host][:name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def cli_example
|
33
|
+
return unless input[:host]
|
34
|
+
<<-EXAMPLE
|
35
|
+
hammer host delete --id '#{task_input[:host][:id]}'
|
36
|
+
EXAMPLE
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ProxyAPI
|
2
|
+
module ForemanChef
|
3
|
+
class ChefProxy
|
4
|
+
PREFIX = 'chef'
|
5
|
+
|
6
|
+
class Node < ProxyAPI::Resource
|
7
|
+
def initialize(args)
|
8
|
+
@url = "#{args[:url]}/#{PREFIX}/nodes"
|
9
|
+
super args
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Client < ProxyAPI::Resource
|
14
|
+
def initialize(args)
|
15
|
+
@url = "#{args[:url]}/#{PREFIX}/clients"
|
16
|
+
super args
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(args)
|
21
|
+
@args = args
|
22
|
+
end
|
23
|
+
|
24
|
+
# Shows a Chef Node entry
|
25
|
+
# [+key+] : String containing the hostname
|
26
|
+
# Returns : Hash representation of host on chef server
|
27
|
+
def show_node(key)
|
28
|
+
Node.new(@args).send(:get, key)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Deletes a Chef Node entry
|
32
|
+
# [+key+] : String containing the hostname
|
33
|
+
# Returns : Boolean status
|
34
|
+
def delete_node(key)
|
35
|
+
Node.new(@args).send(:delete, key)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Shows a Chef Client entry
|
39
|
+
# [+key+] : String containing the hostname
|
40
|
+
# Returns : Hash representation of host on chef server
|
41
|
+
def show_client(key)
|
42
|
+
Client.new(@args).send(:get, key)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Deletes a Chef Client entry
|
46
|
+
# [+key+] : String containing the hostname
|
47
|
+
# Returns : Boolean status
|
48
|
+
def delete_client(key)
|
49
|
+
Client.new(@args).send(:delete, key)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
module Concerns
|
3
|
+
module HostActionSubject
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ForemanTasks::Concerns::ActionSubject
|
6
|
+
include ForemanTasks::Concerns::ActionTriggering
|
7
|
+
|
8
|
+
def destroy_action
|
9
|
+
sync_action!
|
10
|
+
::Actions::ForemanChef::Host::Destroy
|
11
|
+
end
|
12
|
+
|
13
|
+
def action_input_key
|
14
|
+
"host"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
module HostExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
alias_method_chain :set_hostgroup_defaults, :chef_proxy
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_hostgroup_defaults_with_chef_proxy
|
10
|
+
set_hostgroup_defaults_without_chef_proxy
|
11
|
+
return unless hostgroup
|
12
|
+
assign_hostgroup_attributes(['chef_proxy_id'])
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
module HostgroupExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def inherited_chef_proxy_id
|
6
|
+
read_attribute(:chef_proxy_id) || nested(:chef_proxy_id)
|
7
|
+
end
|
8
|
+
|
9
|
+
def chef_proxy
|
10
|
+
if ancestry.present?
|
11
|
+
SmartProxy.with_features('Chef').find_by_id(inherited_chef_proxy_id)
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
module SmartProxyExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
# create or overwrite instance methods...
|
6
|
+
def show_node(fqdn)
|
7
|
+
reply = ProxyAPI::ForemanChef::ChefProxy.new(:url => url).show_node(fqdn)
|
8
|
+
JSON.parse(reply)
|
9
|
+
rescue RestClient::ResourceNotFound
|
10
|
+
logger.debug "Node '#{fqdn}' not found"
|
11
|
+
return false
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_node(fqdn)
|
15
|
+
begin
|
16
|
+
reply = ProxyAPI::ForemanChef::ChefProxy.new(:url => url).delete_node(fqdn)
|
17
|
+
JSON.parse(reply)
|
18
|
+
#rescue RestClient::
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def show_client(fqdn)
|
23
|
+
reply = ProxyAPI::ForemanChef::ChefProxy.new(:url => url).show_client(fqdn)
|
24
|
+
JSON.parse(reply)
|
25
|
+
rescue RestClient::ResourceNotFound
|
26
|
+
logger.debug "Client '#{fqdn}' not found"
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete_client(fqdn)
|
31
|
+
begin
|
32
|
+
reply = ProxyAPI::ForemanChef::ChefProxy.new(:url => url).delete_client(fqdn)
|
33
|
+
JSON.parse(reply)
|
34
|
+
#rescue RestClient::
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Setting::ForemanChef < Setting
|
2
|
+
|
3
|
+
def self.load_defaults
|
4
|
+
# Check the table exists
|
5
|
+
return unless super
|
6
|
+
|
7
|
+
self.transaction do
|
8
|
+
[
|
9
|
+
self.set('auto_deletion', N_("Enable the auto deletion of mapped objects in chef-server through foreman-proxy (currently node and client upon host deletion)"), true),
|
10
|
+
].each { |s| self.create! s.update(:category => "Setting::ForemanChef")}
|
11
|
+
end
|
12
|
+
|
13
|
+
true
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Deface::Override.new(:virtual_path => "hosts/_form",
|
2
|
+
:name => "add_chef_proxy",
|
3
|
+
:insert_bottom => "div#primary",
|
4
|
+
:text => ("<%= chef_proxy_form(f) %>")
|
5
|
+
)
|
6
|
+
|
7
|
+
Deface::Override.new(:virtual_path => "hostgroups/_form",
|
8
|
+
:name => "add_chef_proxy",
|
9
|
+
:insert_bottom => "div#primary",
|
10
|
+
:text => ("<%= chef_proxy_form(f) %>")
|
11
|
+
)
|
12
|
+
|
13
|
+
# strings used above, for the purposes of extraction only, as they're not
|
14
|
+
# detected within the full override template string above
|
15
|
+
N_('Chef proxy')
|
16
|
+
N_('Use this foreman proxy as an entry point to your Chef, node will be managed via this proxy')
|
data/db/seeds.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Feature.find_or_create_by_name('Chef')
|
data/lib/foreman_chef/engine.rb
CHANGED
@@ -1,25 +1,51 @@
|
|
1
|
+
require 'deface'
|
2
|
+
|
1
3
|
module ForemanChef
|
2
4
|
#Inherit from the Rails module of the parent app (Foreman), not the plugin.
|
3
5
|
#Thus, inhereits from ::Rails::Engine and not from Rails::Engine
|
4
6
|
class Engine < ::Rails::Engine
|
5
7
|
|
8
|
+
rake_tasks do
|
9
|
+
Rake::Task['db:seed'].enhance do
|
10
|
+
ForemanChef::Engine.load_seed
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer 'foreman_chef.load_default_settings', :before => :load_config_initializers do
|
15
|
+
require_dependency File.expand_path('../../../app/models/setting/foreman_chef.rb', __FILE__) if (Setting.table_exists? rescue(false))
|
16
|
+
end
|
17
|
+
|
6
18
|
initializer "foreman_chef.load_app_instance_data" do |app|
|
7
19
|
app.config.paths['db/migrate'] += ForemanChef::Engine.paths['db/migrate'].existent
|
8
20
|
end
|
9
21
|
|
10
|
-
initializer
|
22
|
+
initializer "foreman_chef.register_paths" do |app|
|
23
|
+
ForemanTasks.dynflow.config.eager_load_paths.concat(%W[#{ForemanChef::Engine.root}/app/lib/actions])
|
24
|
+
end
|
25
|
+
|
26
|
+
initializer 'foreman_chef.register_plugin', :after => :finisher_hook do |app|
|
11
27
|
Foreman::Plugin.register :foreman_chef do
|
12
28
|
requires_foreman '>= 1.4'
|
13
|
-
end
|
29
|
+
end
|
14
30
|
end
|
15
31
|
|
16
|
-
|
17
|
-
|
18
|
-
|
32
|
+
initializer 'foreman_chef.chef_proxy_form' do |app|
|
33
|
+
ActionView::Base.send :include, ChefProxyForm
|
34
|
+
end
|
35
|
+
|
36
|
+
initializer 'foreman_chef.dynflow_world' do |app|
|
37
|
+
ForemanTasks.dynflow.require!
|
38
|
+
end
|
19
39
|
|
20
|
-
#Include
|
40
|
+
#Include extensions to models in this config.to_prepare block
|
21
41
|
config.to_prepare do
|
42
|
+
::Host::Managed.send :include, ForemanChef::HostExtensions
|
43
|
+
::Hostgroup.send :include, ForemanChef::HostgroupExtensions
|
44
|
+
::Host::Managed.send :include, ChefProxyAssociation
|
45
|
+
::Hostgroup.send :include, ChefProxyAssociation
|
46
|
+
::SmartProxy.send :include, SmartProxyExtensions
|
22
47
|
::FactImporter.register_fact_importer(:foreman_chef, ForemanChef::FactImporter)
|
48
|
+
::Host::Base.send :include, ForemanChef::Concerns::HostActionSubject
|
23
49
|
end
|
24
50
|
end
|
25
51
|
end
|
data/lib/foreman_chef/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_chef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 3.2.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: deface
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: foreman-tasks
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.9
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.9
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: sqlite3
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,9 +73,23 @@ executables: []
|
|
45
73
|
extensions: []
|
46
74
|
extra_rdoc_files: []
|
47
75
|
files:
|
76
|
+
- app/overrides/add_chef_proxy.rb
|
77
|
+
- app/helpers/foreman_chef/chef_proxy_form.rb
|
48
78
|
- app/models/foreman_chef/fact_name.rb
|
79
|
+
- app/models/foreman_chef/smart_proxy_extensions.rb
|
80
|
+
- app/models/foreman_chef/chef_proxy_association.rb
|
81
|
+
- app/models/foreman_chef/hostgroup_extensions.rb
|
82
|
+
- app/models/foreman_chef/host_extensions.rb
|
49
83
|
- app/models/foreman_chef/fact_importer.rb
|
84
|
+
- app/models/foreman_chef/concerns/host_action_subject.rb
|
85
|
+
- app/models/setting/foreman_chef.rb
|
86
|
+
- app/lib/actions/foreman_chef/client/destroy.rb
|
87
|
+
- app/lib/actions/foreman_chef/host/destroy.rb
|
88
|
+
- app/lib/proxy_api/foreman_chef/chef_proxy.rb
|
50
89
|
- config/routes.rb
|
90
|
+
- db/migrate/20140513144804_add_chef_proxy_id_to_hostgroup.rb
|
91
|
+
- db/migrate/20140220145827_add_chef_proxy_id_to_host.rb
|
92
|
+
- db/seeds.rb
|
51
93
|
- lib/foreman_chef/engine.rb
|
52
94
|
- lib/foreman_chef/version.rb
|
53
95
|
- lib/foreman_chef.rb
|
@@ -67,7 +109,6 @@ files:
|
|
67
109
|
- test/dummy/public/404.html
|
68
110
|
- test/dummy/public/500.html
|
69
111
|
- test/dummy/public/422.html
|
70
|
-
- test/dummy/log/development.log
|
71
112
|
- test/dummy/config/database.yml
|
72
113
|
- test/dummy/config/environment.rb
|
73
114
|
- test/dummy/config/locales/en.yml
|
@@ -124,7 +165,6 @@ test_files:
|
|
124
165
|
- test/dummy/public/404.html
|
125
166
|
- test/dummy/public/500.html
|
126
167
|
- test/dummy/public/422.html
|
127
|
-
- test/dummy/log/development.log
|
128
168
|
- test/dummy/config/database.yml
|
129
169
|
- test/dummy/config/environment.rb
|
130
170
|
- test/dummy/config/locales/en.yml
|