1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#
# Author:: Adam Jacob (<adam@hjksolutions.com>)
# Copyright:: Copyright (c) 2008 HJK Solutions, LLC
# License:: GNU General Public License version 2 or later
#
# This program and entire repository 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 2 of the License, or any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
require File.join(File.dirname(__FILE__), "mixin", "params_validate")
require 'rubygems'
require 'facter'
class Chef
class Client
attr_accessor :node, :registration
def initialize()
@node = nil
@safe_name = nil
@registration = nil
@rest = Chef::REST.new(Chef::Config[:registration_url])
end
def run
build_node
register
authenticate
save_node
converge
end
def build_node
node_name = Facter["fqdn"].value ? Facter["fqdn"].value : Facter["hostname"].value
@safe_name = node_name.gsub(/\./, '_')
begin
@node = @rest.get_rest("nodes/#{@safe_name}")
rescue Net::HTTPServerException => e
unless e.message =~ /^404/
raise e
end
end
unless @node
@node ||= Chef::Node.new
@node.name(node_name)
end
Facter.each do |field, value|
@node[field] = value
end
@node
end
def register
@registration = nil
begin
@registration = @rest.get_rest("registrations/#{@safe_name}")
rescue Net::HTTPServerException => e
unless e.message =~ /^404/
raise e
end
end
if @registration
reg = Chef::FileStore.load("registration", @safe_name)
@secret = reg["secret"]
else
create_registration
end
end
def create_registration
@secret = random_password(40)
Chef::FileStore.store("registration", @safe_name, { "secret" => @secret })
@rest.post_rest("registrations", { :id => @safe_name, :password => @secret })
end
def authenticate
response = @rest.post_rest('openid/consumer/start', {
"openid_identifier" => "#{Chef::Config[:openid_url]}/openid/server/node/#{@safe_name}",
"submit" => "Verify"
})
@rest.post_rest(
"#{Chef::Config[:openid_url]}#{response["action"]}",
{ "password" => @secret }
)
end
def save_node
@rest.put_rest("nodes/#{@safe_name}", @node)
end
def converge
results = @rest.get_rest("nodes/#{@safe_name}/compile")
results["collection"].resources.each do |r|
r.collection = results["collection"]
end
cr = Chef::Runner.new(results["node"], results["collection"])
cr.converge
end
protected
def random_password(len)
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
newpass
end
end
end
|