chef 0.7.16 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of chef might be problematic. Click here for more details.
- data/README.rdoc +11 -10
- data/bin/chef-client +2 -2
- data/bin/chef-solo +1 -1
- data/bin/knife +27 -0
- data/bin/shef +49 -0
- data/distro/README +2 -0
- data/distro/{debian → common}/man/man1/chef-indexer.1 +0 -0
- data/distro/{debian → common}/man/man1/chef-server.1 +0 -0
- data/distro/{debian → common}/man/man8/chef-client.8 +0 -0
- data/distro/{debian → common}/man/man8/chef-solo.8 +0 -0
- data/distro/common/man/man8/knife.8 +375 -0
- data/distro/redhat/etc/init.d/chef-client +8 -4
- data/distro/redhat/etc/init.d/chef-server +16 -15
- data/distro/redhat/etc/init.d/chef-server-webui +78 -0
- data/distro/redhat/etc/init.d/chef-solr +76 -0
- data/distro/redhat/etc/init.d/chef-solr-indexer +75 -0
- data/distro/redhat/etc/sysconfig/chef-client +10 -0
- data/distro/redhat/etc/sysconfig/chef-server +10 -0
- data/distro/redhat/etc/sysconfig/chef-server-webui +10 -0
- data/distro/redhat/etc/sysconfig/chef-solr +9 -0
- data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
- data/distro/suse/etc/init.d/chef-client +121 -0
- data/lib/chef.rb +1 -1
- data/lib/chef/api_client.rb +263 -0
- data/lib/chef/application.rb +1 -1
- data/lib/chef/application/client.rb +21 -3
- data/lib/chef/application/knife.rb +144 -0
- data/lib/chef/application/server.rb +2 -1
- data/lib/chef/application/solo.rb +9 -2
- data/lib/chef/cache.rb +61 -0
- data/lib/chef/cache/checksum.rb +70 -0
- data/lib/chef/certificate.rb +154 -0
- data/lib/chef/client.rb +123 -220
- data/lib/chef/compile.rb +9 -21
- data/lib/chef/config.rb +67 -10
- data/lib/chef/cookbook.rb +49 -22
- data/lib/chef/cookbook/metadata.rb +85 -5
- data/lib/chef/cookbook_loader.rb +4 -4
- data/lib/chef/couchdb.rb +99 -30
- data/lib/chef/daemon.rb +1 -1
- data/lib/chef/data_bag.rb +215 -0
- data/lib/chef/data_bag_item.rb +219 -0
- data/lib/chef/exceptions.rb +3 -0
- data/lib/chef/index_queue.rb +29 -0
- data/lib/chef/index_queue/amqp_client.rb +106 -0
- data/lib/chef/index_queue/consumer.rb +76 -0
- data/lib/chef/index_queue/indexable.rb +74 -0
- data/lib/chef/knife.rb +309 -0
- data/lib/chef/knife/client_bulk_delete.rb +40 -0
- data/lib/chef/knife/client_create.rb +62 -0
- data/lib/chef/knife/client_delete.rb +37 -0
- data/lib/chef/knife/client_edit.rb +37 -0
- data/lib/chef/knife/client_list.rb +40 -0
- data/lib/chef/knife/client_reregister.rb +48 -0
- data/lib/chef/knife/client_show.rb +42 -0
- data/lib/chef/knife/configure.rb +123 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +46 -0
- data/lib/chef/knife/cookbook_delete.rb +41 -0
- data/lib/chef/knife/cookbook_download.rb +57 -0
- data/lib/chef/knife/cookbook_list.rb +41 -0
- data/lib/chef/knife/cookbook_metadata.rb +87 -0
- data/lib/chef/knife/cookbook_show.rb +75 -0
- data/lib/chef/knife/cookbook_upload.rb +179 -0
- data/lib/chef/knife/data_bag_create.rb +43 -0
- data/lib/chef/knife/data_bag_delete.rb +43 -0
- data/lib/chef/knife/data_bag_edit.rb +49 -0
- data/lib/chef/knife/data_bag_list.rb +42 -0
- data/lib/chef/knife/data_bag_show.rb +40 -0
- data/lib/chef/knife/ec2_instance_data.rb +46 -0
- data/lib/chef/knife/index_rebuild.rb +51 -0
- data/lib/chef/knife/node_bulk_delete.rb +43 -0
- data/lib/chef/knife/node_create.rb +39 -0
- data/lib/chef/knife/node_delete.rb +36 -0
- data/lib/chef/knife/node_edit.rb +36 -0
- data/lib/chef/knife/node_from_file.rb +42 -0
- data/lib/chef/knife/node_list.rb +41 -0
- data/lib/chef/knife/node_run_list_add.rb +64 -0
- data/lib/chef/knife/node_run_list_remove.rb +45 -0
- data/lib/chef/knife/node_show.rb +46 -0
- data/lib/chef/knife/role_bulk_delete.rb +44 -0
- data/lib/chef/knife/role_create.rb +44 -0
- data/lib/chef/knife/role_delete.rb +36 -0
- data/lib/chef/knife/role_edit.rb +37 -0
- data/lib/chef/knife/role_from_file.rb +46 -0
- data/lib/chef/knife/role_list.rb +40 -0
- data/lib/chef/knife/role_show.rb +43 -0
- data/lib/chef/knife/search.rb +94 -0
- data/lib/chef/knife/ssh.rb +170 -0
- data/lib/chef/log.rb +30 -8
- data/lib/chef/mixin/checksum.rb +2 -7
- data/lib/chef/mixin/command.rb +32 -13
- data/lib/chef/mixin/convert_to_class_name.rb +15 -0
- data/lib/chef/mixin/deep_merge.rb +199 -11
- data/lib/chef/mixin/generate_url.rb +18 -9
- data/lib/chef/mixin/language.rb +29 -1
- data/lib/chef/mixin/language_include_attribute.rb +56 -0
- data/lib/chef/mixin/language_include_recipe.rb +53 -0
- data/lib/chef/mixin/params_validate.rb +25 -12
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +2 -0
- data/lib/chef/mixin/template.rb +11 -1
- data/lib/chef/mixin/xml_escape.rb +87 -0
- data/lib/chef/node.rb +144 -122
- data/lib/chef/openid_registration.rb +12 -5
- data/lib/chef/platform.rb +89 -47
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cron.rb +5 -6
- data/lib/chef/provider/deploy.rb +43 -10
- data/lib/chef/provider/deploy/revision.rb +2 -3
- data/lib/chef/provider/erl_call.rb +72 -0
- data/lib/chef/provider/file.rb +8 -4
- data/lib/chef/provider/git.rb +10 -5
- data/lib/chef/provider/group/dscl.rb +128 -0
- data/lib/chef/provider/http_request.rb +6 -2
- data/lib/chef/provider/ifconfig.rb +1 -0
- data/lib/chef/provider/link.rb +1 -1
- data/lib/chef/provider/log.rb +53 -0
- data/lib/chef/provider/mdadm.rb +88 -0
- data/lib/chef/provider/mount/mount.rb +1 -1
- data/lib/chef/provider/package.rb +1 -1
- data/lib/chef/provider/package/easy_install.rb +106 -0
- data/lib/chef/provider/package/pacman.rb +101 -0
- data/lib/chef/provider/package/portage.rb +1 -1
- data/lib/chef/provider/package/rpm.rb +10 -8
- data/lib/chef/provider/package/yum-dump.py +22 -3
- data/lib/chef/provider/package/yum.rb +32 -8
- data/lib/chef/provider/package/zypper.rb +132 -0
- data/lib/chef/provider/remote_directory.rb +58 -49
- data/lib/chef/provider/remote_file.rb +1 -1
- data/lib/chef/provider/route.rb +136 -80
- data/lib/chef/provider/ruby_block.rb +18 -1
- data/lib/chef/provider/service/arch.rb +109 -0
- data/lib/chef/provider/service/freebsd.rb +0 -1
- data/lib/chef/provider/service/simple.rb +2 -3
- data/lib/chef/provider/service/upstart.rb +191 -0
- data/lib/chef/provider/subversion.rb +12 -4
- data/lib/chef/provider/template.rb +85 -53
- data/lib/chef/provider/user.rb +1 -1
- data/lib/chef/provider/user/dscl.rb +277 -0
- data/lib/chef/provider/user/useradd.rb +1 -0
- data/lib/chef/recipe.rb +2 -41
- data/lib/chef/resource.rb +9 -3
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/deploy.rb +16 -2
- data/lib/chef/resource/easy_install_package.rb +41 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/freebsd_package.rb +35 -0
- data/lib/chef/resource/log.rb +62 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/pacman_package.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +21 -2
- data/lib/chef/resource/scm.rb +8 -0
- data/lib/chef/resource/subversion.rb +1 -0
- data/lib/chef/resource/user.rb +5 -2
- data/lib/chef/resource/yum_package.rb +36 -0
- data/lib/chef/resource_collection.rb +17 -9
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/rest.rb +166 -81
- data/lib/chef/role.rb +114 -38
- data/lib/chef/run_list.rb +15 -6
- data/lib/chef/runner.rb +13 -11
- data/lib/chef/search/query.rb +60 -0
- data/lib/chef/shef.rb +220 -0
- data/lib/chef/shef/ext.rb +297 -0
- data/lib/chef/shef/shef_session.rb +175 -0
- data/lib/chef/streaming_cookbook_uploader.rb +187 -0
- data/lib/chef/tasks/chef_repo.rake +53 -155
- data/lib/chef/util/file_edit.rb +94 -96
- data/lib/chef/webui_user.rb +233 -0
- metadata +219 -63
- data/distro/debian/etc/init.d/chef-indexer +0 -175
- data/distro/redhat/etc/chef/client.rb +0 -16
- data/distro/redhat/etc/chef/indexer.rb +0 -10
- data/distro/redhat/etc/chef/server.rb +0 -22
- data/distro/redhat/etc/init.d/chef-indexer +0 -76
- data/lib/chef/application/indexer.rb +0 -141
- data/lib/chef/queue.rb +0 -145
- data/lib/chef/search.rb +0 -88
- data/lib/chef/search/result.rb +0 -64
- data/lib/chef/search_index.rb +0 -77
- data/lib/chef/util/fileedit.rb +0 -121
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Jan Zimmek (<jan.zimmek@web.de>)
|
3
|
+
# Copyright:: Copyright (c) 2010 Jan Zimmek
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/resource/package'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Resource
|
23
|
+
class PacmanPackage < Chef::Resource::Package
|
24
|
+
|
25
|
+
def initialize(name, collection=nil, node=nil)
|
26
|
+
super(name, collection, node)
|
27
|
+
@resource_name = :pacman_package
|
28
|
+
@provider = Chef::Provider::Package::Pacman
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,15 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
|
+
# Author:: AJ Christensen (<aj@opscode.com>)
|
4
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
1
20
|
class Chef
|
2
21
|
class Resource
|
3
22
|
class RubyBlock < Chef::Resource
|
4
23
|
def initialize(name, collection=nil, node=nil)
|
5
24
|
super(name, collection, node)
|
6
25
|
@resource_name = :ruby_block
|
7
|
-
@action =
|
26
|
+
@action = "create"
|
8
27
|
@allowed_actions.push(:create)
|
9
28
|
end
|
10
29
|
|
11
30
|
def block(&block)
|
12
|
-
if block
|
31
|
+
if block_given? and block
|
13
32
|
@block = block
|
14
33
|
else
|
15
34
|
@block
|
data/lib/chef/resource/scm.rb
CHANGED
data/lib/chef/resource/user.rb
CHANGED
@@ -33,7 +33,10 @@ class Chef
|
|
33
33
|
@shell = nil
|
34
34
|
@password = nil
|
35
35
|
@action = :create
|
36
|
-
@supports = {
|
36
|
+
@supports = {
|
37
|
+
:manage_home => false,
|
38
|
+
:non_unique => false
|
39
|
+
}
|
37
40
|
@allowed_actions.push(:create, :remove, :modify, :manage, :lock, :unlock)
|
38
41
|
end
|
39
42
|
|
@@ -95,4 +98,4 @@ class Chef
|
|
95
98
|
|
96
99
|
end
|
97
100
|
end
|
98
|
-
end
|
101
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Author:: AJ Christensen (<aj@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2008 Opscode, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/resource/package'
|
20
|
+
require 'chef/provider/package/yum'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Resource
|
24
|
+
class YumPackage < Chef::Resource::Package
|
25
|
+
|
26
|
+
def initialize(name, collection=nil, node=nil)
|
27
|
+
super(name, collection, node)
|
28
|
+
@resource_name = :yum_package
|
29
|
+
@provider = Chef::Provider::Package::Yum
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
@@ -18,10 +18,13 @@
|
|
18
18
|
#
|
19
19
|
|
20
20
|
require 'chef/resource'
|
21
|
+
require 'chef/resource_collection/stepable_iterator'
|
21
22
|
|
22
23
|
class Chef
|
23
24
|
class ResourceCollection
|
24
25
|
include Enumerable
|
26
|
+
|
27
|
+
attr_reader :iterator
|
25
28
|
|
26
29
|
def initialize
|
27
30
|
@resources = Array.new
|
@@ -29,6 +32,10 @@ class Chef
|
|
29
32
|
@insert_after_idx = nil
|
30
33
|
end
|
31
34
|
|
35
|
+
def all_resources
|
36
|
+
@resources
|
37
|
+
end
|
38
|
+
|
32
39
|
def [](index)
|
33
40
|
@resources[index]
|
34
41
|
end
|
@@ -67,23 +74,24 @@ class Chef
|
|
67
74
|
end
|
68
75
|
|
69
76
|
def push(*args)
|
70
|
-
args.flatten.each do |
|
71
|
-
is_chef_resource(
|
72
|
-
@resources.push(
|
73
|
-
@resources_by_name[
|
77
|
+
args.flatten.each do |arg|
|
78
|
+
is_chef_resource(arg)
|
79
|
+
@resources.push(arg)
|
80
|
+
@resources_by_name[arg.to_s] = @resources.length - 1
|
74
81
|
end
|
75
82
|
end
|
76
83
|
|
77
84
|
def each
|
78
|
-
@resources.each do |
|
79
|
-
yield
|
85
|
+
@resources.each do |resource|
|
86
|
+
yield resource
|
80
87
|
end
|
81
88
|
end
|
82
89
|
|
83
|
-
def execute_each_resource
|
84
|
-
@
|
90
|
+
def execute_each_resource(&resource_exec_block)
|
91
|
+
@iterator = StepableIterator.for_collection(@resources)
|
92
|
+
@iterator.each_with_index do |resource, idx|
|
85
93
|
@insert_after_idx = idx
|
86
|
-
yield
|
94
|
+
yield resource
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# Author:: Daniel DeLeo (<dan@kallistec.com>)
|
2
|
+
# Copyright:: Copyright (c) 2009 Daniel DeLeo
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class ResourceCollection
|
20
|
+
class StepableIterator
|
21
|
+
|
22
|
+
def self.for_collection(new_collection)
|
23
|
+
instance = new(new_collection)
|
24
|
+
instance
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :collection
|
28
|
+
attr_reader :position
|
29
|
+
|
30
|
+
def initialize(collection=[])
|
31
|
+
@position = 0
|
32
|
+
@paused = false
|
33
|
+
@collection = collection
|
34
|
+
end
|
35
|
+
|
36
|
+
def size
|
37
|
+
collection.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def each(&block)
|
41
|
+
reset_iteration(block)
|
42
|
+
@iterator_type = :element
|
43
|
+
iterate
|
44
|
+
end
|
45
|
+
|
46
|
+
def each_index(&block)
|
47
|
+
reset_iteration(block)
|
48
|
+
@iterator_type = :index
|
49
|
+
iterate
|
50
|
+
end
|
51
|
+
|
52
|
+
def each_with_index(&block)
|
53
|
+
reset_iteration(block)
|
54
|
+
@iterator_type = :element_with_index
|
55
|
+
iterate
|
56
|
+
end
|
57
|
+
|
58
|
+
def paused?
|
59
|
+
@paused
|
60
|
+
end
|
61
|
+
|
62
|
+
def pause
|
63
|
+
@paused = true
|
64
|
+
end
|
65
|
+
|
66
|
+
def resume
|
67
|
+
@paused = false
|
68
|
+
iterate
|
69
|
+
end
|
70
|
+
|
71
|
+
def rewind
|
72
|
+
@position = 0
|
73
|
+
end
|
74
|
+
|
75
|
+
def skip_back(skips=1)
|
76
|
+
@position -= skips
|
77
|
+
end
|
78
|
+
|
79
|
+
def skip_forward(skips=1)
|
80
|
+
@position += skips
|
81
|
+
end
|
82
|
+
|
83
|
+
def step
|
84
|
+
return nil if @position == size
|
85
|
+
call_iterator_block
|
86
|
+
@position += 1
|
87
|
+
end
|
88
|
+
|
89
|
+
def iterate_on(iteration_type, &block)
|
90
|
+
@iterator_type = iteration_type
|
91
|
+
@iterator_block = block
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def reset_iteration(iterator_block)
|
97
|
+
@iterator_block = iterator_block
|
98
|
+
@position = 0
|
99
|
+
@paused = false
|
100
|
+
end
|
101
|
+
|
102
|
+
def iterate
|
103
|
+
while @position < size && !paused?
|
104
|
+
step
|
105
|
+
end
|
106
|
+
collection
|
107
|
+
end
|
108
|
+
|
109
|
+
def call_iterator_block
|
110
|
+
case @iterator_type
|
111
|
+
when :element
|
112
|
+
@iterator_block.call(collection[@position])
|
113
|
+
when :index
|
114
|
+
@iterator_block.call(@position)
|
115
|
+
when :element_with_index
|
116
|
+
@iterator_block.call(collection[@position], @position)
|
117
|
+
else
|
118
|
+
raise "42error: someone forgot to set @iterator_type, wtf?"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
data/lib/chef/rest.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Adam Jacob (<adam@opscode.com>)
|
3
3
|
# Author:: Thom May (<thom@clearairturbulence.org>)
|
4
|
-
#
|
4
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
5
|
+
# Author:: Christopher Brown (<cb@opscode.com>)
|
6
|
+
# Author:: Christopher Walters (<cw@opscode.com>)
|
7
|
+
# Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
|
5
8
|
# License:: Apache License, Version 2.0
|
6
9
|
#
|
7
10
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -18,12 +21,15 @@
|
|
18
21
|
#
|
19
22
|
|
20
23
|
require 'chef/mixin/params_validate'
|
21
|
-
require 'chef/openid_registration'
|
22
24
|
require 'net/https'
|
23
25
|
require 'uri'
|
24
26
|
require 'json'
|
25
27
|
require 'tempfile'
|
26
28
|
require 'singleton'
|
29
|
+
require 'mixlib/authentication/signedheaderauth'
|
30
|
+
require 'chef/api_client'
|
31
|
+
|
32
|
+
include Mixlib::Authentication::SignedHeaderAuth
|
27
33
|
|
28
34
|
class Chef
|
29
35
|
class REST
|
@@ -32,47 +38,61 @@ class Chef
|
|
32
38
|
include Singleton
|
33
39
|
end
|
34
40
|
|
35
|
-
attr_accessor :url, :cookies
|
41
|
+
attr_accessor :url, :cookies, :client_name, :signing_key, :signing_key_filename, :sign_on_redirect, :sign_request
|
36
42
|
|
37
|
-
def initialize(url)
|
43
|
+
def initialize(url, client_name=Chef::Config[:node_name], signing_key_filename=Chef::Config[:client_key])
|
38
44
|
@url = url
|
39
45
|
@cookies = CookieJar.instance
|
46
|
+
@client_name = client_name
|
47
|
+
if signing_key_filename
|
48
|
+
@signing_key_filename = signing_key_filename
|
49
|
+
@signing_key = load_signing_key(signing_key_filename)
|
50
|
+
@sign_request = true
|
51
|
+
else
|
52
|
+
@signing_key = nil
|
53
|
+
@sign_request = false
|
54
|
+
end
|
55
|
+
@sign_on_redirect = true
|
40
56
|
end
|
41
|
-
|
42
|
-
|
43
|
-
def register(user, pass, validation_token=nil)
|
44
|
-
Chef::Log.debug("Registering #{user} for an openid")
|
45
|
-
registration = nil
|
57
|
+
|
58
|
+
def load_signing_key(key)
|
46
59
|
begin
|
47
|
-
|
48
|
-
rescue
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
53
|
-
unless registration
|
54
|
-
post_rest(
|
55
|
-
"registrations",
|
56
|
-
{
|
57
|
-
:id => user,
|
58
|
-
:password => pass,
|
59
|
-
:validation_token => validation_token
|
60
|
-
}
|
61
|
-
)
|
60
|
+
IO.read(key)
|
61
|
+
rescue StandardError=>se
|
62
|
+
Chef::Log.error "Failed to read the private key #{key}: #{se.inspect}, #{se.backtrace}"
|
63
|
+
raise Chef::Exceptions::PrivateKeyMissing, "I cannot read #{key}, which you told me to use to sign requests!"
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
#
|
66
|
-
def
|
67
|
-
Chef::
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
67
|
+
# Register the client
|
68
|
+
def register(name=Chef::Config[:node_name], destination=Chef::Config[:client_key])
|
69
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination} - check permissions?" if (File.exists?(destination) && !File.writable?(destination))
|
70
|
+
|
71
|
+
nc = Chef::ApiClient.new
|
72
|
+
nc.name(name)
|
73
|
+
|
74
|
+
catch(:done) do
|
75
|
+
retries = Chef::Config[:client_registration_retries] || 5
|
76
|
+
0.upto(retries) do |n|
|
77
|
+
begin
|
78
|
+
response = nc.save(true, true)
|
79
|
+
Chef::Log.debug("Registration response: #{response.inspect}")
|
80
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "The response from the server did not include a private key!" unless response.has_key?("private_key")
|
81
|
+
# Write out the private key
|
82
|
+
file = File.open(destination, File::WRONLY|File::EXCL|File::CREAT, 0600)
|
83
|
+
file.print(response["private_key"])
|
84
|
+
file.close
|
85
|
+
throw :done
|
86
|
+
rescue IOError
|
87
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination}"
|
88
|
+
rescue Net::HTTPFatalError => e
|
89
|
+
Chef::Log.warn("Failed attempt #{n} of #{retries+1} on client creation")
|
90
|
+
raise unless e.response.code == "500"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
true
|
76
96
|
end
|
77
97
|
|
78
98
|
# Send an HTTP GET request to the path
|
@@ -81,23 +101,23 @@ class Chef
|
|
81
101
|
# path:: The path to GET
|
82
102
|
# raw:: Whether you want the raw body returned, or JSON inflated. Defaults
|
83
103
|
# to JSON inflated.
|
84
|
-
def get_rest(path, raw=false)
|
85
|
-
run_request(:GET, create_url(path), false, 10, raw)
|
104
|
+
def get_rest(path, raw=false, headers={})
|
105
|
+
run_request(:GET, create_url(path), headers, false, 10, raw)
|
86
106
|
end
|
87
107
|
|
88
108
|
# Send an HTTP DELETE request to the path
|
89
|
-
def delete_rest(path)
|
90
|
-
run_request(:DELETE, create_url(path))
|
109
|
+
def delete_rest(path, headers={})
|
110
|
+
run_request(:DELETE, create_url(path), headers)
|
91
111
|
end
|
92
112
|
|
93
113
|
# Send an HTTP POST request to the path
|
94
|
-
def post_rest(path, json)
|
95
|
-
run_request(:POST, create_url(path), json)
|
114
|
+
def post_rest(path, json, headers={})
|
115
|
+
run_request(:POST, create_url(path), headers, json)
|
96
116
|
end
|
97
117
|
|
98
118
|
# Send an HTTP PUT request to the path
|
99
|
-
def put_rest(path, json)
|
100
|
-
run_request(:PUT, create_url(path), json)
|
119
|
+
def put_rest(path, json, headers={})
|
120
|
+
run_request(:PUT, create_url(path), headers, json)
|
101
121
|
end
|
102
122
|
|
103
123
|
def create_url(path)
|
@@ -108,6 +128,19 @@ class Chef
|
|
108
128
|
end
|
109
129
|
end
|
110
130
|
|
131
|
+
def sign_request(http_method, path, private_key, user_id, body = "", host="localhost")
|
132
|
+
#body = "" if body == false
|
133
|
+
timestamp = Time.now.utc.iso8601
|
134
|
+
sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
|
135
|
+
:http_method=>http_method,
|
136
|
+
:path => path,
|
137
|
+
:body=>body,
|
138
|
+
:user_id=>user_id,
|
139
|
+
:timestamp=>timestamp)
|
140
|
+
signed = sign_obj.sign(private_key).merge({:host => host})
|
141
|
+
signed.inject({}){|memo, kv| memo["#{kv[0].to_s.upcase}"] = kv[1];memo}
|
142
|
+
end
|
143
|
+
|
111
144
|
# Actually run an HTTP request. First argument is the HTTP method,
|
112
145
|
# which should be one of :GET, :PUT, :POST or :DELETE. Next is the
|
113
146
|
# URL, then an object to include in the body (which will be converted with
|
@@ -117,7 +150,8 @@ class Chef
|
|
117
150
|
# the helper methods (get_rest, post_rest, etc.)
|
118
151
|
#
|
119
152
|
# Will return the body of the response on success.
|
120
|
-
def run_request(method, url, data=false, limit=10, raw=false)
|
153
|
+
def run_request(method, url, headers={}, data=false, limit=10, raw=false)
|
154
|
+
|
121
155
|
http_retry_delay = Chef::Config[:http_retry_delay]
|
122
156
|
http_retry_count = Chef::Config[:http_retry_count]
|
123
157
|
|
@@ -128,22 +162,46 @@ class Chef
|
|
128
162
|
http.use_ssl = true
|
129
163
|
if Chef::Config[:ssl_verify_mode] == :verify_none
|
130
164
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
165
|
+
elsif Chef::Config[:ssl_verify_mode] == :verify_peer
|
166
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
167
|
+
end
|
168
|
+
if Chef::Config[:ssl_ca_path] and File.exists?(Chef::Config[:ssl_ca_path])
|
169
|
+
http.ca_path = Chef::Config[:ssl_ca_path]
|
170
|
+
elsif Chef::Config[:ssl_ca_file] and File.exists?(Chef::Config[:ssl_ca_file])
|
171
|
+
http.ca_file = Chef::Config[:ssl_ca_file]
|
131
172
|
end
|
132
|
-
if File.exists?(Chef::Config[:ssl_client_cert])
|
173
|
+
if Chef::Config[:ssl_client_cert] && File.exists?(Chef::Config[:ssl_client_cert])
|
133
174
|
http.cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:ssl_client_cert]))
|
134
175
|
http.key = OpenSSL::PKey::RSA.new(File.read(Chef::Config[:ssl_client_key]))
|
135
176
|
end
|
136
177
|
end
|
178
|
+
|
137
179
|
http.read_timeout = Chef::Config[:rest_timeout]
|
138
|
-
|
180
|
+
|
139
181
|
unless raw
|
140
|
-
headers = {
|
182
|
+
headers = headers.merge({
|
141
183
|
'Accept' => "application/json",
|
142
|
-
}
|
184
|
+
})
|
143
185
|
end
|
186
|
+
|
187
|
+
headers['X-Chef-Version'] = ::Chef::VERSION
|
188
|
+
|
144
189
|
if @cookies.has_key?("#{url.host}:#{url.port}")
|
145
190
|
headers['Cookie'] = @cookies["#{url.host}:#{url.port}"]
|
146
191
|
end
|
192
|
+
|
193
|
+
json_body = data ? data.to_json : nil
|
194
|
+
|
195
|
+
if @sign_request
|
196
|
+
raise ArgumentError, "Cannot sign the request without a client name, check that :node_name is assigned" if @client_name.nil?
|
197
|
+
Chef::Log.debug("Signing the request as #{@client_name}")
|
198
|
+
if json_body
|
199
|
+
headers.merge!(sign_request(method, url.path, OpenSSL::PKey::RSA.new(@signing_key), @client_name, json_body, "#{url.host}:#{url.port}"))
|
200
|
+
else
|
201
|
+
headers.merge!(sign_request(method, url.path, OpenSSL::PKey::RSA.new(@signing_key), @client_name, "", "#{url.host}:#{url.port}"))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
147
205
|
req = nil
|
148
206
|
case method
|
149
207
|
when :GET
|
@@ -152,12 +210,16 @@ class Chef
|
|
152
210
|
req = Net::HTTP::Get.new(req_path, headers)
|
153
211
|
when :POST
|
154
212
|
headers["Content-Type"] = 'application/json' if data
|
155
|
-
|
156
|
-
|
213
|
+
req_path = "#{url.path}"
|
214
|
+
req_path << "?#{url.query}" if url.query
|
215
|
+
req = Net::HTTP::Post.new(req_path, headers)
|
216
|
+
req.body = json_body if json_body
|
157
217
|
when :PUT
|
158
218
|
headers["Content-Type"] = 'application/json' if data
|
159
|
-
|
160
|
-
|
219
|
+
req_path = "#{url.path}"
|
220
|
+
req_path << "?#{url.query}" if url.query
|
221
|
+
req = Net::HTTP::Put.new(req_path, headers)
|
222
|
+
req.body = json_body if json_body
|
161
223
|
when :DELETE
|
162
224
|
req_path = "#{url.path}"
|
163
225
|
req_path << "?#{url.query}" if url.query
|
@@ -165,16 +227,19 @@ class Chef
|
|
165
227
|
else
|
166
228
|
raise ArgumentError, "You must provide :GET, :PUT, :POST or :DELETE as the method"
|
167
229
|
end
|
230
|
+
|
231
|
+
Chef::Log.debug("Sending HTTP Request via #{req.method} to #{url.host}:#{url.port}#{req.path}")
|
168
232
|
|
169
233
|
# Optionally handle HTTP Basic Authentication
|
170
234
|
req.basic_auth(url.user, url.password) if url.user
|
171
235
|
|
172
|
-
Chef::Log.debug("Sending HTTP Request via #{req.method} to #{req.path}")
|
173
236
|
res = nil
|
174
237
|
tf = nil
|
175
|
-
|
238
|
+
http_attempts = 0
|
176
239
|
|
177
240
|
begin
|
241
|
+
http_attempts += 1
|
242
|
+
|
178
243
|
res = http.request(req) do |response|
|
179
244
|
if raw
|
180
245
|
tf = Tempfile.new("chef-rest")
|
@@ -199,40 +264,60 @@ class Chef
|
|
199
264
|
end
|
200
265
|
response
|
201
266
|
end
|
267
|
+
|
268
|
+
if res.kind_of?(Net::HTTPSuccess)
|
269
|
+
if res['set-cookie']
|
270
|
+
@cookies["#{url.host}:#{url.port}"] = res['set-cookie']
|
271
|
+
end
|
272
|
+
if res['content-type'] =~ /json/
|
273
|
+
response_body = res.body.chomp
|
274
|
+
JSON.parse(response_body)
|
275
|
+
else
|
276
|
+
if raw
|
277
|
+
tf
|
278
|
+
else
|
279
|
+
res.body
|
280
|
+
end
|
281
|
+
end
|
282
|
+
elsif res.kind_of?(Net::HTTPFound) or res.kind_of?(Net::HTTPMovedPermanently)
|
283
|
+
if res['set-cookie']
|
284
|
+
@cookies["#{url.host}:#{url.port}"] = res['set-cookie']
|
285
|
+
end
|
286
|
+
@sign_request = false if @sign_on_redirect == false
|
287
|
+
run_request(:GET, create_url(res['location']), {}, false, limit - 1, raw)
|
288
|
+
else
|
289
|
+
if res['content-type'] =~ /json/
|
290
|
+
exception = JSON.parse(res.body)
|
291
|
+
Chef::Log.debug("HTTP Request Returned #{res.code} #{res.message}: #{exception["error"].respond_to?(:join) ? exception["error"].join(", ") : exception["error"]}")
|
292
|
+
end
|
293
|
+
res.error!
|
294
|
+
end
|
295
|
+
|
202
296
|
rescue Errno::ECONNREFUSED
|
203
|
-
|
204
|
-
|
205
|
-
|
297
|
+
if http_retry_count - http_attempts + 1 > 0
|
298
|
+
Chef::Log.error("Connection refused connecting to #{url.host}:#{url.port} for #{req.path}, retry #{http_attempts}/#{http_retry_count}")
|
299
|
+
sleep(http_retry_delay)
|
300
|
+
retry
|
301
|
+
end
|
206
302
|
raise Errno::ECONNREFUSED, "Connection refused connecting to #{url.host}:#{url.port} for #{req.path}, giving up"
|
207
303
|
rescue Timeout::Error
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
end
|
213
|
-
|
214
|
-
if res.kind_of?(Net::HTTPSuccess)
|
215
|
-
if res['set-cookie']
|
216
|
-
@cookies["#{url.host}:#{url.port}"] = res['set-cookie']
|
304
|
+
if http_retry_count - http_attempts + 1 > 0
|
305
|
+
Chef::Log.error("Timeout connecting to #{url.host}:#{url.port} for #{req.path}, retry #{http_attempts}/#{http_retry_count}")
|
306
|
+
sleep(http_retry_delay)
|
307
|
+
retry
|
217
308
|
end
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
if
|
222
|
-
|
223
|
-
|
224
|
-
|
309
|
+
raise Timeout::Error, "Timeout connecting to #{url.host}:#{url.port} for #{req.path}, giving up"
|
310
|
+
rescue Net::HTTPServerException
|
311
|
+
if res.kind_of?(Net::HTTPForbidden)
|
312
|
+
if http_retry_count - http_attempts + 1 > 0
|
313
|
+
Chef::Log.error("Received 403 Forbidden against #{url.host}:#{url.port} for #{req.path}, retry #{http_attempts}/#{http_retry_count}")
|
314
|
+
sleep(http_retry_delay)
|
315
|
+
retry
|
225
316
|
end
|
226
317
|
end
|
227
|
-
|
228
|
-
if res['set-cookie']
|
229
|
-
@cookies["#{url.host}:#{url.port}"] = res['set-cookie']
|
230
|
-
end
|
231
|
-
run_request(:GET, create_url(res['location']), false, limit - 1, raw)
|
232
|
-
else
|
233
|
-
res.error!
|
318
|
+
raise
|
234
319
|
end
|
235
320
|
end
|
236
|
-
|
321
|
+
|
237
322
|
end
|
238
323
|
end
|