foreman_default_hostgroup 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjIyNTViYmQ0MmVjZTkxZDU2N2JlZDNkY2ZiNmRiNTJkNTE1MzYxOQ==
4
+ MjlmNWYzMGJjMGZiMTNiNWYwNTU4YTJiNThlYjk5MjZhZjBhYzM0Yw==
5
5
  data.tar.gz: !binary |-
6
- MDQ1ZTIwZDczYWYyNzgwYzQxYTk1ODdiOTgzMmI5MWJmMzAyYzQzZA==
6
+ Yjg1MjJhMTFlYzY0YjQ4YWM2MTdlY2E3YjY4YmFkYmM3Njc0ZjZmMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDQyMTNlOWU0ZWIyYmQ0MzA5MGNiNmQ3Njc4M2JkMTBiMDM0MTA3OTlkMTNk
10
- M2NmYzU2ZjNkMjc0MzYzZGEzNzhkNDM2MTlmODMwMWU5ZjIzOTEyYWEzZDU3
11
- OTRhMWRiYTAxNzllOGE5ZjkwYmQyZTg5ZDY4MzM1ZmM1NDk1ODc=
9
+ YTMzNGEzNDA3OGM1YTEwZGQ4MmRhMWI0MjZlYzgwNzZiYmE0MGE2NDZjYjMz
10
+ NGU5OGI0ZGQ4YTMyMWE1NzcxOTY0OWQ5ODlmYmQ4ODU4YjA0NWM0MzhhZTkz
11
+ NDczODMwNDRiNTNjN2FhYjgxODdhMzM5YjFlM2IwZTk5YTU0MzM=
12
12
  data.tar.gz: !binary |-
13
- M2E4MDBlNDg2ZDBiYjMxNWE3OWY1OTJiMzU3NGMyYTQwOGYwNjNkMWIxZTg0
14
- ZGU1ZTRmMzcxYmIxNDljNjc4OGEwNGRiZWUyODJjZWUxOTE5N2FmOTdiYmY1
15
- ZWVkMzgwN2FlNWVlMDMxZmQ2YmU2Nzg2OTQ4OTgxNmFmNjdlNTk=
13
+ NjliZmFjMTEyZWUzYTQ0MWJlZmI5Y2IxYTA5MDU3N2FiNGE2YWE3NmY3MDk1
14
+ YjVmYzQyMjUyMzMyOGZlMDlmNThjMjI0NWZjZDNkMWEwNjk5MjBiYmNiYzkw
15
+ NWVlNWUwMWJhYTkyZGRlMjdiODdmODg3YzhhNGM5NDVmOWI3Y2I=
data/README.md CHANGED
@@ -13,25 +13,38 @@ for how to install Foreman plugins
13
13
  | Foreman Version | Plugin Version |
14
14
  | --------------- | --------------:|
15
15
  | <= 1.2 | 0.1.0 |
16
- | >= 1.3 | 1.0.1 |
16
+ | 1.3 | 1.0.1 |
17
+ | 1.4 | 1.1.0 |
18
+ | >= 1.5 | 2.0.0 |
17
19
 
18
20
  ## Usage
19
21
 
20
- Go to `Settings -> DefaultHostgroup` and enter the name of the default
21
- hostgroup. Leaving this blank disables the plugin. Nested Hostgroups should be
22
- specified with the full label, e.g. `Base/Level1/Level2`
22
+ The configuration is done inside foreman's plugin settings directory which is
23
+ ```~foreman/config/settings.plugins.d/```.
23
24
 
24
- Once set, any fact upload to `/api/hosts/facts` for a Host with no Hostgroup set
25
- will cause the Hostgroup to be set to the value in the Settings. This happens
26
- *before* the ENC data is downloaded, meaning it applies for a Host's very first
27
- run.
25
+ You can simply copy ```default_hostgroup.yaml.example``` and adjust it to fit
26
+ your needs. The simplest example would be:
28
27
 
29
- The plugin only sets the Hostgroup for Hosts which have no Hostgroup, and no
30
- reports (i.e new Hosts only).
28
+ ```
29
+ ---
30
+ :default_hostgroup:
31
+ :map:
32
+ "Default": ".*"
33
+ ```
34
+
35
+ *Important Note:* You have to restart foreman in order to apply changes in
36
+ ```default_hostgroup.yaml```!
37
+
38
+ There are also two more settings under ```Settings -> DefaultHostgroup```
39
+
40
+ | Setting | Description |
41
+ | ------- | ----------- |
42
+ | ```force_hostgroup_match``` | Setting this to ```true``` will perform matching even on hosts that already have a hostgroup set. Enabling this needs ```force_hostgroup_match_only_new``` to be ```false```. Default: ```false``` |
43
+ | ```force_hostgroup_match_only_new``` | Setting this to ```true``` will only perform matching when a host uploads its facts for the first time, i.e. after provisioning or when adding an existing puppetmaster and thus its nodes into foreman. Default: ```true``` |
31
44
 
32
45
  ## TODO
33
46
 
34
- * Tests
47
+ * Deface the Hostgroup UI to add the regular expressions directly into the Hostgroup
35
48
 
36
49
  ## Contributing
37
50
 
@@ -7,7 +7,8 @@ class Setting::DefaultHostgroup < ::Setting
7
7
 
8
8
  Setting.transaction do
9
9
  [
10
- self.set('default_hostgroup', 'The default Hostgroup to place new Hosts in', ''),
10
+ self.set('force_hostgroup_match', 'Apply hostgroup matching even if a host already has one.', false),
11
+ self.set('force_hostgroup_match_only_new', 'Apply hostgroup matching only on new hosts', true),
11
12
  ].compact.each { |s| self.create s.update(:category => 'Setting::DefaultHostgroup')}
12
13
  end
13
14
 
@@ -1,36 +1,64 @@
1
- require 'yaml'
2
1
  module DefaultHostgroupManagedHostPatch
3
2
  def self.included(base)
4
3
  base.extend ClassMethods
5
4
  base.class_eval do
6
5
  class << self
7
- alias_method_chain :importHostAndFacts, :apply_hostgroup
6
+ alias_method_chain :import_host_and_facts, :match_hostgroup
8
7
  end
9
8
  end
10
9
  end
11
10
 
12
11
  module ClassMethods
13
- def importHostAndFacts_with_apply_hostgroup hostname, facts, certname = nil, proxy_id = nil
14
- host, result = importHostAndFacts_without_apply_hostgroup(hostname, facts, certname, proxy_id)
15
- Rails.logger.debug "DefaultHostgroup: performing Hostgroup check"
12
+ def import_host_and_facts_with_match_hostgroup hostname, facts, certname = nil, proxy_id = nil
13
+ raise Foreman::Exception.new "Could not load default_hostgroup settings, check config" unless SETTINGS[:default_hostgroup]
14
+ raise Foreman::Exception.new "Could not load default_hostgroup map from settings, check config." unless SETTINGS[:default_hostgroup][:map]
16
15
 
17
- unless valid_hostgroup?
18
- Rails.logger.debug "DefaultHostgroup: Could not find Hostgroup '#{Setting[:default_hostgroup]}'"
19
- return host, result
16
+ Rails.logger.debug "DefaultHostgroupMatch: performing Hostgroup match"
17
+ host, result = import_host_and_facts_without_match_hostgroup(hostname, facts, certname, proxy_id)
18
+
19
+ if Setting[:force_hostgroup_match_only_new]
20
+ # host.new_record? will only test for the early return in the core method, a real host
21
+ # will have already been saved at least once.
22
+ unless host.present? && !host.new_record? && host.hostgroup.nil? && host.reports.empty?
23
+
24
+ Rails.logger.debug "DefaultHostgroupMatch: skipping, host exists"
25
+ return host, result
26
+ end
27
+ end
28
+
29
+ unless Setting[:force_hostgroup_match]
30
+ if host.hostgroup.present?
31
+ Rails.logger.debug "DefaultHostgroupMatch: skipping, host has hostgroup"
32
+ return host, result
33
+ end
20
34
  end
21
35
 
22
- # host.new_record? will only test for the early return in the core method, a real host
23
- # will have already been saved at least once.
24
- if host.present? && !host.new_record? && host.hostgroup.nil? && host.reports.empty?
25
- host.hostgroup = Hostgroup.find_by_label(Setting[:default_hostgroup])
26
- host.save(:validate => false)
27
- Rails.logger.debug "DefaultHostgroup: added #{host.name} to #{host.hostgroup.label}"
36
+ map = SETTINGS[:default_hostgroup][:map]
37
+ new_hostgroup = nil
38
+
39
+ map.each do |hostgroup, regex|
40
+ unless valid_hostgroup?(hostgroup)
41
+ Rails.logger.error "DefaultHostgroupMatch: #{hostgroup} is not a valid hostgroup, skipping."
42
+ next
43
+ end
44
+ regex.gsub!(/(\A\/|\/\z)/, '')
45
+ if Regexp.new(regex).match(hostname)
46
+ new_hostgroup = Hostgroup.find_by_title(hostgroup)
47
+ break
48
+ end
28
49
  end
50
+
51
+ return host, result unless new_hostgroup
52
+
53
+ host.hostgroup = new_hostgroup
54
+ host.save(:validate => false)
55
+ Rails.logger.info "DefaultHostgroupMatch: #{hostname} added to #{new_hostgroup}"
56
+
29
57
  return host, result
30
58
  end
31
59
 
32
- def valid_hostgroup?
33
- Hostgroup.find_by_label(Setting[:default_hostgroup]) ? true : false
60
+ def valid_hostgroup?(hostgroup)
61
+ Hostgroup.find_by_title(hostgroup) ? true : false
34
62
  end
35
63
  end
36
64
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanDefaultHostgroup
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -10,36 +10,113 @@ class DefaultHostgroupTest < ActiveSupport::TestCase
10
10
  return JSON.parse(File.read(File.expand_path(File.dirname(__FILE__) + relative_path)))
11
11
  end
12
12
 
13
- def setup_hostgroup
13
+ def setup_hostgroup_match
14
14
  # The settings.yml fixture in Core wipes out the Setting table,
15
15
  # so we use FactoryGirl to re-create it
16
16
  FactoryGirl.create(:setting,
17
- :name => 'default_hostgroup',
17
+ :name => 'force_hostgroup_match',
18
18
  :category => 'Setting::DefaultHostgroup')
19
- @hostgroup = Hostgroup.create :name => "MyGroup"
20
- Setting[:default_hostgroup] = @hostgroup.name
19
+ FactoryGirl.create(:setting,
20
+ :name => 'force_hostgroup_match_only_new',
21
+ :category => 'Setting::DefaultHostgroup')
22
+ Setting[:force_hostgroup_match] = false
23
+ Setting[:force_hostgroup_match_only_new] = true
24
+ SETTINGS[:default_hostgroup] = Hash.new
25
+ end
26
+
27
+ test "full matching regex not enclosed in /" do
28
+ setup_hostgroup_match
29
+ SETTINGS[:default_hostgroup][:map] = { "Test Full" => '^sinn1636.lan$' }
30
+
31
+ hostgroup = Hostgroup.create(:name => "Test Full")
32
+ raw = parse_json_fixture('/facts.json')
33
+
34
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
35
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
36
+ end
37
+
38
+ test "partial matching regex enclosed in /" do
39
+ setup_hostgroup_match
40
+ SETTINGS[:default_hostgroup][:map] = { "Test Partial" => '/\.lan$/' }
41
+
42
+ hostgroup = Hostgroup.create(:name => "Test Partial")
43
+ raw = parse_json_fixture('/facts.json')
44
+
45
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
46
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
47
+ end
48
+
49
+ test "invalid hostgroup does nothing" do
50
+ setup_hostgroup_match
51
+ SETTINGS[:default_hostgroup][:map] = { "Nonexistent Group" => '.*', "Existent Group" => '/\.lan$/' }
52
+
53
+ hostgroup = Hostgroup.create(:name => "Existent Group")
54
+ raw = parse_json_fixture('/facts.json')
55
+
56
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
57
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
58
+ end
59
+
60
+ test "default hostgroup" do
61
+ setup_hostgroup_match
62
+ SETTINGS[:default_hostgroup][:map] = { "Test Default" => '.*' }
63
+
64
+ hostgroup = Hostgroup.create(:name => "Test Default")
65
+ raw = parse_json_fixture('/facts.json')
66
+
67
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
68
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
21
69
  end
22
70
 
23
- test "a new, fact-imported, host has a default hostgroup set" do
24
- setup_hostgroup
71
+ test "host already has a hostgroup" do
72
+ setup_hostgroup_match
73
+ SETTINGS[:default_hostgroup][:map] = { "Test Default" => '.*' }
74
+
75
+ hostgroup = Hostgroup.create(:name => "Test Group")
76
+ Hostgroup.create(:name => "Test Default")
25
77
  raw = parse_json_fixture('/facts.json')
26
- assert Host.importHostAndFacts(raw['name'], raw['facts'])
27
- assert_equal @hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
78
+
79
+ host, result = Host.import_host_and_facts_without_match_hostgroup(raw['name'], raw['facts'])
80
+ host.hostgroup = hostgroup
81
+ host.save(:validate => false)
82
+
83
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
84
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
28
85
  end
29
86
 
30
- test "an invalid hostgroup setting does nothing" do
31
- setup_hostgroup
32
- Setting[:default_hostgroup] = "doesnotexist"
87
+ test "force hostgroup match on host with existing hostgroup" do
88
+ setup_hostgroup_match
89
+ Setting[:force_hostgroup_match] = true
90
+ Setting[:force_hostgroup_match_only_new] = false
91
+ SETTINGS[:default_hostgroup][:map] = { "Test Default" => '.*' }
92
+
93
+ hostgroup = Hostgroup.create(:name => "Test Group")
94
+ default = Hostgroup.create(:name => "Test Default")
33
95
  raw = parse_json_fixture('/facts.json')
34
- assert Host.importHostAndFacts(raw['name'], raw['facts'])
35
- refute Host.find_by_name('sinn1636.lan').hostgroup
96
+
97
+ host, result = Host.import_host_and_facts_without_match_hostgroup(raw['name'], raw['facts'])
98
+ host.hostgroup = hostgroup
99
+ host.save(:validate => false)
100
+
101
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
102
+ assert_equal default, Host.find_by_name('sinn1636.lan').hostgroup
36
103
  end
37
104
 
38
- # Contrived example to check new plugin factories are loaded
39
- test "my factory exists" do
40
- refute Environment.find_by_name('defaulthostgrouptest')
41
- FactoryGirl.create(:environment)
42
- assert Environment.find_by_name('defaulthostgrouptest')
105
+ test "hostgroup is not updated if host is not new" do
106
+ setup_hostgroup_match
107
+ Setting[:force_hostgroup_match] = true
108
+ SETTINGS[:default_hostgroup][:map] = { "Test Default" => '.*' }
109
+
110
+ hostgroup = Hostgroup.create(:name => "Test Group")
111
+ Hostgroup.create(:name => "Test Default")
112
+ raw = parse_json_fixture('/facts.json')
113
+
114
+ host, result = Host.import_host_and_facts_without_match_hostgroup(raw['name'], raw['facts'])
115
+ host.hostgroup = hostgroup
116
+ host.save(:validate => false)
117
+
118
+ assert Host.import_host_and_facts(raw['name'], raw['facts'])
119
+ assert_equal hostgroup, Host.find_by_name('sinn1636.lan').hostgroup
43
120
  end
44
121
 
45
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_default_hostgroup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Sutcliffe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-07 00:00:00.000000000 Z
11
+ date: 2014-04-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Adds the option to specify a default hostgroup for new hosts created
14
14
  from facts/reports
@@ -28,7 +28,6 @@ files:
28
28
  - lib/foreman_default_hostgroup.rb
29
29
  - lib/foreman_default_hostgroup/engine.rb
30
30
  - lib/foreman_default_hostgroup/version.rb
31
- - test/factories/environments.rb
32
31
  - test/test_plugin_helper.rb
33
32
  - test/unit/default_hostgroup_test.rb
34
33
  - test/unit/facts.json
@@ -57,7 +56,6 @@ signing_key:
57
56
  specification_version: 4
58
57
  summary: Default Hostgroup Plugin for Foreman
59
58
  test_files:
60
- - test/factories/environments.rb
59
+ - test/test_plugin_helper.rb
61
60
  - test/unit/facts.json
62
61
  - test/unit/default_hostgroup_test.rb
63
- - test/test_plugin_helper.rb
@@ -1,5 +0,0 @@
1
- FactoryGirl.define do
2
- factory :environment do
3
- name 'defaulthostgrouptest'
4
- end
5
- end