foreman_chef 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/foreman_chef/fact_importer.rb +35 -19
- data/app/models/foreman_chef/fact_parser.rb +122 -0
- data/app/views/foreman/unattended/snippets/_chef_client_bootstrap.erb +11 -1
- data/db/seeds.rb +1 -0
- data/lib/foreman_chef/engine.rb +1 -0
- data/lib/foreman_chef/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b773fa035adf626fde30885aee0bef06f0d4ba46
|
4
|
+
data.tar.gz: 38d3baf59f382e1a26ccd24485b0bdb30a409cea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c555e4843a61e3b7d2ed2425b2697a39407fce06bebe8d208cd0c24e9986181c8460a50a241ca961c888c7441e4af4648af4cb34a56d8891d3ebdfecb19de7fc
|
7
|
+
data.tar.gz: 13c080d9e7980bb11f134d102f975f51169ce4663d21d5b9662e0f8334652398a551bd188fd3f52b80234d7187e88b5b686f8f59dec528fa8e123afc4cce8eb9
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module ForemanChef
|
2
2
|
class FactImporter < ::FactImporter
|
3
|
+
class FactNameImportError < StandardError; end
|
4
|
+
|
3
5
|
def fact_name_class
|
4
6
|
ForemanChef::FactName
|
5
7
|
end
|
@@ -18,7 +20,7 @@ module ForemanChef
|
|
18
20
|
|
19
21
|
def add_new_facts
|
20
22
|
@counters[:added] = 0
|
21
|
-
add_missing_facts(unsparse(original_facts))
|
23
|
+
add_missing_facts(Sparser.new.unsparse(original_facts))
|
22
24
|
logger.debug("Merging facts for '#{host}': added #{@counters[:added]} facts")
|
23
25
|
end
|
24
26
|
|
@@ -30,9 +32,21 @@ module ForemanChef
|
|
30
32
|
if fact_names[name_with_prefix].present?
|
31
33
|
fact_name_id = fact_names[name_with_prefix]
|
32
34
|
else
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
# fact names didn't contain fact_name so we create new one
|
36
|
+
fact_name = fact_name_class.new(:name => name_with_prefix,
|
37
|
+
:parent_id => parent,
|
38
|
+
:compose => compose)
|
39
|
+
if fact_name.save
|
40
|
+
fact_name_id = fact_name.id
|
41
|
+
elsif fact_name.errors[:name].present?
|
42
|
+
# saving could have failed because of raise condition with another import process,
|
43
|
+
# so if the error is on name uniqueness, we try to reload conflicting name and use it
|
44
|
+
conflicting_fact_name = fact_name_class.where(:name => fact_name.name).first
|
45
|
+
fact_name_id = conflicting_fact_name.id
|
46
|
+
else
|
47
|
+
raise FactNameImportError, "unable to save fact name, errors: #{fact_name.errors.full_messages.join("\n")}"
|
48
|
+
end
|
49
|
+
fact_name_id
|
36
50
|
end
|
37
51
|
|
38
52
|
if compose
|
@@ -89,23 +103,25 @@ module ForemanChef
|
|
89
103
|
hash.sort_by { |k, v| k.to_s }
|
90
104
|
end
|
91
105
|
|
92
|
-
|
93
|
-
hash
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
106
|
+
class Sparser
|
107
|
+
def sparse(hash, options={})
|
108
|
+
hash.map do |k, v|
|
109
|
+
prefix = (options.fetch(:prefix, [])+[k])
|
110
|
+
next sparse(v, options.merge(:prefix => prefix)) if v.is_a? Hash
|
111
|
+
{ prefix.join(options.fetch(:separator, FactName::SEPARATOR)) => v }
|
112
|
+
end.reduce(:merge) || Hash.new
|
113
|
+
end
|
99
114
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
115
|
+
def unsparse(hash, options={})
|
116
|
+
ret = Hash.new
|
117
|
+
sparse(hash).each do |k, v|
|
118
|
+
current = ret
|
119
|
+
key = k.to_s.split(options.fetch(:separator, FactName::SEPARATOR))
|
120
|
+
current = (current[key.shift] ||= Hash.new) until (key.size<=1)
|
121
|
+
current[key.first] = v
|
122
|
+
end
|
123
|
+
return ret
|
107
124
|
end
|
108
|
-
return ret
|
109
125
|
end
|
110
126
|
end
|
111
127
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module ForemanChef
|
2
|
+
class FactParser < ::FactParser
|
3
|
+
VIRTUAL = /\A([a-z0-9]+)[:.](\d+)\Z/
|
4
|
+
VIRTUAL_NAMES = /#{VIRTUAL}|#{BRIDGES}|#{BONDS}/
|
5
|
+
|
6
|
+
def operatingsystem
|
7
|
+
os_name = facts['lsb::id'] || facts['platform']
|
8
|
+
release = facts['lsb::release'] || fact['platform_version']
|
9
|
+
major, minor = release.split('.')
|
10
|
+
description = facts['lsb::description']
|
11
|
+
release_name = facts['lsb::codename']
|
12
|
+
|
13
|
+
begin
|
14
|
+
klass = os_name.constantize
|
15
|
+
rescue NameError => e
|
16
|
+
logger.debug "unknown operating system #{os_name}, fallback to generic type"
|
17
|
+
klass = Operatingsystem
|
18
|
+
end
|
19
|
+
|
20
|
+
args = { :name => os_name, :major => major, :minor => minor }
|
21
|
+
klass.where(args).first || klass.new(args.merge(:description => description, :release_name => release_name)).save!
|
22
|
+
end
|
23
|
+
|
24
|
+
def environment
|
25
|
+
name = facts['environment'] || Setting[:default_puppet_environment]
|
26
|
+
Environment.find_or_create_by_name name
|
27
|
+
end
|
28
|
+
|
29
|
+
def architecture
|
30
|
+
name = facts['kernel::machine']
|
31
|
+
name = "x86_64" if name == "amd64"
|
32
|
+
Architecture.find_or_create_by_name name unless name.blank?
|
33
|
+
end
|
34
|
+
|
35
|
+
def model
|
36
|
+
if facts['virtualization'].present?
|
37
|
+
name = facts['virtualization']['system']
|
38
|
+
else
|
39
|
+
name = facts['dmi::system::product_name']
|
40
|
+
end
|
41
|
+
Model.find_or_create_by_name(name.strip) unless name.blank?
|
42
|
+
end
|
43
|
+
|
44
|
+
def domain
|
45
|
+
name = facts['domain']
|
46
|
+
Domain.find_or_create_by_name name unless name.blank?
|
47
|
+
end
|
48
|
+
|
49
|
+
def ipmi_interface
|
50
|
+
if facts['ipmi::mac_address'].present?
|
51
|
+
{ 'ipaddress' => facts['ipmi::address'], 'macaddress' => facts['ipmi::mac_address'] }.with_indifferent_access
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def certname
|
56
|
+
facts['chef_node_name']
|
57
|
+
end
|
58
|
+
|
59
|
+
def support_interfaces_parsing?
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_interfaces?
|
64
|
+
support_interfaces_parsing? && !Setting['ignore_puppet_facts_for_provisioning']
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# meant to be implemented in inheriting classes
|
70
|
+
# should return hash with indifferent access in following format:
|
71
|
+
# { 'link': 'true',
|
72
|
+
# 'macaddress': '00:00:00:00:00:FF',
|
73
|
+
# 'ipaddress': nil,
|
74
|
+
# 'any_other_fact': 'value' }
|
75
|
+
#
|
76
|
+
# note that link and macaddress are mandatory
|
77
|
+
def get_facts_for_interface(interface)
|
78
|
+
facts = interfaces_hash[interface]
|
79
|
+
hash = {
|
80
|
+
'link' => facts['state'] == 'up',
|
81
|
+
'macaddress' => get_address_by_family(facts['addresses'], 'lladdr'),
|
82
|
+
'ipaddress' => get_address_by_family(facts['addresses'], 'inet'),
|
83
|
+
}
|
84
|
+
hash['tag'] = facts['vlan']['id'] if facts['vlan'].present?
|
85
|
+
hash.with_indifferent_access
|
86
|
+
end
|
87
|
+
|
88
|
+
# meant to be implemented in inheriting classes
|
89
|
+
# should return array of interfaces names, e.g.
|
90
|
+
# ['eth0', 'eth0.0', 'eth1']
|
91
|
+
def get_interfaces
|
92
|
+
interfaces_hash.keys
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_address_by_family(addresses, family)
|
96
|
+
addresses.detect { |address, attributes| attributes['family'] == family }.try(:first)
|
97
|
+
end
|
98
|
+
|
99
|
+
def network_hash
|
100
|
+
@network_hash ||= ForemanChef::FactImporter::Sparser.new.unsparse(facts.select { |k, v| k =~ /\Anetwork::interfaces::/})['network']
|
101
|
+
end
|
102
|
+
|
103
|
+
def interfaces_hash
|
104
|
+
@interfaces_hash ||= network_hash['interfaces']
|
105
|
+
end
|
106
|
+
|
107
|
+
# adds attributes like virtual
|
108
|
+
def set_additional_attributes(attributes, name)
|
109
|
+
if name =~ VIRTUAL_NAMES
|
110
|
+
attributes[:virtual] = true
|
111
|
+
if $1.nil? && name =~ BRIDGES
|
112
|
+
attributes[:bridge] = true
|
113
|
+
else
|
114
|
+
attributes[:attached_to] = $1
|
115
|
+
end
|
116
|
+
else
|
117
|
+
attributes[:virtual] = false
|
118
|
+
end
|
119
|
+
attributes
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -8,12 +8,22 @@ cat << 'EOF' > /etc/chef/validation.pem
|
|
8
8
|
<%= @host.params['chef_validation_private_key'] %>
|
9
9
|
EOF
|
10
10
|
|
11
|
+
## If chef_server_certificate is present, install it into /etc/chef/trusted_certs
|
12
|
+
<% chef_server_certificate = @host.params['chef_server_certificate'] -%>
|
13
|
+
<% if !chef_server_certificate.nil? && !chef_server_certificate.empty? -%>
|
14
|
+
mkdir -p /etc/chef/trusted_certs
|
15
|
+
chmod 0755 /etc/chef/trusted_certs
|
16
|
+
cat << 'EOF' > /etc/chef/trusted_certs/chef-server.pem
|
17
|
+
<%= chef_server_certificate %>
|
18
|
+
EOF
|
19
|
+
<% end -%>
|
20
|
+
|
11
21
|
echo "Configuring chef client.rb"
|
12
22
|
cat << 'EOF' > /etc/chef/client.rb
|
13
23
|
log_level :info
|
14
24
|
log_location STDOUT
|
15
25
|
chef_server_url "<%= @host.params['chef_server_url'] %>"
|
16
|
-
validation_client_name "
|
26
|
+
validation_client_name "<%= @host.params['chef_validator_name'] -%>"
|
17
27
|
file_backup_path "/var/lib/chef"
|
18
28
|
file_cache_path "/var/cache/chef"
|
19
29
|
pid_file "/var/run/chef/client.pid"
|
data/db/seeds.rb
CHANGED
@@ -21,6 +21,7 @@ parameters = [
|
|
21
21
|
{ :name => 'chef_validation_private_key', :value => 'UNSPECIFIED, you must upload your validation key here' },
|
22
22
|
{ :name => 'chef_bootstrap_template', :value => 'chef-client omnibus bootstrap' },
|
23
23
|
{ :name => 'chef_server_certificate', :value => '' },
|
24
|
+
{ :name => 'chef_validator_name', :value => 'chef-validator' },
|
24
25
|
]
|
25
26
|
|
26
27
|
parameters.each do |parameter|
|
data/lib/foreman_chef/engine.rb
CHANGED
@@ -47,6 +47,7 @@ module ForemanChef
|
|
47
47
|
::Hostgroup.send :include, ChefProxyAssociation
|
48
48
|
::SmartProxy.send :include, SmartProxyExtensions
|
49
49
|
::FactImporter.register_fact_importer(:foreman_chef, ForemanChef::FactImporter)
|
50
|
+
::FactParser.register_fact_importer(:foreman_chef, ForemanChef::FactParser)
|
50
51
|
::Host::Base.send :include, ForemanChef::Concerns::HostActionSubject
|
51
52
|
end
|
52
53
|
|
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.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marek Hulan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -75,6 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- app/overrides/add_chef_proxy.rb
|
77
77
|
- app/helpers/foreman_chef/chef_proxy_form.rb
|
78
|
+
- app/models/foreman_chef/fact_parser.rb
|
78
79
|
- app/models/foreman_chef/fact_name.rb
|
79
80
|
- app/models/foreman_chef/smart_proxy_extensions.rb
|
80
81
|
- app/models/foreman_chef/chef_proxy_association.rb
|