foreman_chef 0.0.4 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9116ff8cbc2d9611bc315667f4da6a871fc4ee70
4
- data.tar.gz: 5fd304dd80a76a7b0c469ae1ba8bc4df3c8e9b38
3
+ metadata.gz: 48b50dcd6355797ece89dee99d3f9ebef0d347e4
4
+ data.tar.gz: 79ae27dc6b1c7d23b6d7d2acc942b3f6a94aea2a
5
5
  SHA512:
6
- metadata.gz: 6a511666f44ada17e426fb497c578b879c0de51e98192ad19bd20a01fa2235e6df7662a18da95e6c9f327e078b1aeec1ede5bfbcadd8319b8ae2e38ffabbfacf
7
- data.tar.gz: 98a678f999e673e98b05a8b8684767b266187f3d5fd69d5e28513ab2170fedb6bfd9504e74c144089648d958062cbaf8559912c8d8364aea9f8d6132d6e80d7e
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 improter to Foreman. It basically means that when you setup your chef
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 gemfile
8
+ To install this plugin you just have to add this line to your Gemfile.
9
9
 
10
10
  ```ruby
11
- gem 'foreman_chef', :git => 'https://github.com/ares/foreman_chef'
11
+ gem 'foreman_chef'
12
12
  ```
13
13
 
14
- and run bundle install. Don't forget to restart foreman after this change.
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
- This project rocks and uses MIT-LICENSE.
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,10 @@
1
+ module ForemanChef
2
+ module ChefProxyAssociation
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ belongs_to :chef_proxy, :class_name => "SmartProxy"
7
+ end
8
+
9
+ end
10
+ 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
@@ -4,6 +4,10 @@ module ForemanChef
4
4
  ForemanChef::FactName
5
5
  end
6
6
 
7
+ def self.authorized_smart_proxy_features
8
+ 'Chef'
9
+ end
10
+
7
11
  def self.support_background
8
12
  true
9
13
  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')
@@ -0,0 +1,5 @@
1
+ class AddChefProxyIdToHost < ActiveRecord::Migration
2
+ def change
3
+ add_column :hosts, :chef_proxy_id, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddChefProxyIdToHostgroup < ActiveRecord::Migration
2
+ def change
3
+ add_column :hostgroups, :chef_proxy_id, :integer
4
+ end
5
+ end
data/db/seeds.rb ADDED
@@ -0,0 +1 @@
1
+ Feature.find_or_create_by_name('Chef')
@@ -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 'foreman_chef.register_plugin', :after=> :finisher_hook do |app|
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 if Foreman::Plugin rescue(false)
29
+ end
14
30
  end
15
31
 
16
- #initializer 'foreman_chef.helper' do |app|
17
- # ActionView::Base.send :include, FactValuesHelper
18
- #end
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 extenstions to models in this config.to_prepare block
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
@@ -1,3 +1,3 @@
1
1
  module ForemanChef
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
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
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: 2014-01-22 00:00:00.000000000 Z
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
@@ -1,4 +0,0 @@
1
- Connecting to database specified by database.yml
2
- Connecting to database specified by database.yml
3
- Connecting to database specified by database.yml
4
- Connecting to database specified by database.yml