runa-chef 0.8.0.1
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.
- data/LICENSE +201 -0
- data/README.rdoc +136 -0
- data/bin/chef-client +26 -0
- data/bin/chef-solo +26 -0
- data/bin/knife +27 -0
- data/bin/shef +45 -0
- data/distro/README +2 -0
- data/distro/common/man/man1/chef-indexer.1 +42 -0
- data/distro/common/man/man1/chef-server.1 +108 -0
- data/distro/common/man/man8/chef-client.8 +61 -0
- data/distro/common/man/man8/chef-solo.8 +58 -0
- data/distro/common/man/man8/knife.8 +359 -0
- data/distro/debian/etc/init.d/chef-client +175 -0
- data/distro/debian/etc/init.d/chef-indexer +175 -0
- data/distro/debian/etc/init.d/chef-server +120 -0
- data/distro/redhat/etc/init.d/chef-client +78 -0
- data/distro/redhat/etc/init.d/chef-indexer +76 -0
- data/distro/redhat/etc/init.d/chef-server +78 -0
- data/distro/redhat/etc/sysconfig/chef-client +10 -0
- data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
- data/distro/redhat/etc/sysconfig/chef-server +10 -0
- data/distro/suse/etc/init.d/chef-client +121 -0
- data/lib/chef.rb +49 -0
- data/lib/chef/api_client.rb +269 -0
- data/lib/chef/application.rb +98 -0
- data/lib/chef/application/agent.rb +18 -0
- data/lib/chef/application/client.rb +214 -0
- data/lib/chef/application/knife.rb +138 -0
- data/lib/chef/application/server.rb +19 -0
- data/lib/chef/application/solo.rb +214 -0
- 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 +323 -0
- data/lib/chef/compile.rb +158 -0
- data/lib/chef/config.rb +195 -0
- data/lib/chef/cookbook.rb +198 -0
- data/lib/chef/cookbook/metadata.rb +487 -0
- data/lib/chef/cookbook/metadata/version.rb +87 -0
- data/lib/chef/cookbook_loader.rb +180 -0
- data/lib/chef/couchdb.rb +273 -0
- data/lib/chef/daemon.rb +170 -0
- data/lib/chef/data_bag.rb +216 -0
- data/lib/chef/data_bag_item.rb +227 -0
- data/lib/chef/exceptions.rb +39 -0
- data/lib/chef/file_cache.rb +205 -0
- data/lib/chef/knife.rb +300 -0
- data/lib/chef/knife/client_bulk_delete.rb +41 -0
- data/lib/chef/knife/client_create.rb +55 -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 +84 -0
- data/lib/chef/knife/cookbook_bulk_delete.rb +47 -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 +173 -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/node_bulk_delete.rb +44 -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 +45 -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/log.rb +39 -0
- data/lib/chef/mixin/check_helper.rb +31 -0
- data/lib/chef/mixin/checksum.rb +32 -0
- data/lib/chef/mixin/command.rb +390 -0
- data/lib/chef/mixin/convert_to_class_name.rb +57 -0
- data/lib/chef/mixin/create_path.rb +56 -0
- data/lib/chef/mixin/deep_merge.rb +33 -0
- data/lib/chef/mixin/find_preferred_file.rb +92 -0
- data/lib/chef/mixin/from_file.rb +50 -0
- data/lib/chef/mixin/generate_url.rb +58 -0
- data/lib/chef/mixin/language.rb +107 -0
- 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 +197 -0
- data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
- data/lib/chef/mixin/template.rb +94 -0
- data/lib/chef/nanite.rb +100 -0
- data/lib/chef/node.rb +463 -0
- data/lib/chef/node/attribute.rb +412 -0
- data/lib/chef/openid_registration.rb +181 -0
- data/lib/chef/platform.rb +268 -0
- data/lib/chef/provider.rb +101 -0
- data/lib/chef/provider/breakpoint.rb +36 -0
- data/lib/chef/provider/cron.rb +184 -0
- data/lib/chef/provider/deploy.rb +314 -0
- data/lib/chef/provider/deploy/revision.rb +70 -0
- data/lib/chef/provider/deploy/timestamped.rb +33 -0
- data/lib/chef/provider/directory.rb +72 -0
- data/lib/chef/provider/erl_call.rb +72 -0
- data/lib/chef/provider/execute.rb +58 -0
- data/lib/chef/provider/file.rb +195 -0
- data/lib/chef/provider/git.rb +203 -0
- data/lib/chef/provider/group.rb +120 -0
- data/lib/chef/provider/group/dscl.rb +128 -0
- data/lib/chef/provider/group/gpasswd.rb +50 -0
- data/lib/chef/provider/group/groupadd.rb +78 -0
- data/lib/chef/provider/group/pw.rb +88 -0
- data/lib/chef/provider/group/usermod.rb +57 -0
- data/lib/chef/provider/http_request.rb +106 -0
- data/lib/chef/provider/ifconfig.rb +131 -0
- data/lib/chef/provider/link.rb +157 -0
- data/lib/chef/provider/mdadm.rb +88 -0
- data/lib/chef/provider/mount.rb +117 -0
- data/lib/chef/provider/mount/mount.rb +208 -0
- data/lib/chef/provider/package.rb +160 -0
- data/lib/chef/provider/package/apt.rb +110 -0
- data/lib/chef/provider/package/dpkg.rb +109 -0
- data/lib/chef/provider/package/easy_install.rb +106 -0
- data/lib/chef/provider/package/freebsd.rb +153 -0
- data/lib/chef/provider/package/macports.rb +105 -0
- data/lib/chef/provider/package/portage.rb +124 -0
- data/lib/chef/provider/package/rpm.rb +99 -0
- data/lib/chef/provider/package/rubygems.rb +136 -0
- data/lib/chef/provider/package/yum-dump.py +125 -0
- data/lib/chef/provider/package/yum.rb +175 -0
- data/lib/chef/provider/package/zypper.rb +132 -0
- data/lib/chef/provider/remote_directory.rb +126 -0
- data/lib/chef/provider/remote_file.rb +141 -0
- data/lib/chef/provider/route.rb +118 -0
- data/lib/chef/provider/ruby_block.rb +33 -0
- data/lib/chef/provider/script.rb +42 -0
- data/lib/chef/provider/service.rb +135 -0
- data/lib/chef/provider/service/debian.rb +64 -0
- data/lib/chef/provider/service/freebsd.rb +156 -0
- data/lib/chef/provider/service/gentoo.rb +54 -0
- data/lib/chef/provider/service/init.rb +71 -0
- data/lib/chef/provider/service/redhat.rb +62 -0
- data/lib/chef/provider/service/simple.rb +114 -0
- data/lib/chef/provider/subversion.rb +156 -0
- data/lib/chef/provider/template.rb +175 -0
- data/lib/chef/provider/user.rb +170 -0
- data/lib/chef/provider/user/dscl.rb +280 -0
- data/lib/chef/provider/user/pw.rb +113 -0
- data/lib/chef/provider/user/useradd.rb +108 -0
- data/lib/chef/recipe.rb +105 -0
- data/lib/chef/resource.rb +380 -0
- data/lib/chef/resource/apt_package.rb +34 -0
- data/lib/chef/resource/bash.rb +33 -0
- data/lib/chef/resource/breakpoint.rb +35 -0
- data/lib/chef/resource/cron.rb +179 -0
- data/lib/chef/resource/csh.rb +33 -0
- data/lib/chef/resource/deploy.rb +359 -0
- data/lib/chef/resource/deploy_revision.rb +35 -0
- data/lib/chef/resource/directory.rb +76 -0
- data/lib/chef/resource/dpkg_package.rb +34 -0
- data/lib/chef/resource/easy_install_package.rb +41 -0
- data/lib/chef/resource/erl_call.rb +83 -0
- data/lib/chef/resource/execute.rb +127 -0
- data/lib/chef/resource/file.rb +84 -0
- data/lib/chef/resource/gem_package.rb +41 -0
- data/lib/chef/resource/git.rb +36 -0
- data/lib/chef/resource/group.rb +70 -0
- data/lib/chef/resource/http_request.rb +52 -0
- data/lib/chef/resource/ifconfig.rb +134 -0
- data/lib/chef/resource/link.rb +78 -0
- data/lib/chef/resource/macports_package.rb +29 -0
- data/lib/chef/resource/mdadm.rb +82 -0
- data/lib/chef/resource/mount.rb +135 -0
- data/lib/chef/resource/package.rb +80 -0
- data/lib/chef/resource/perl.rb +33 -0
- data/lib/chef/resource/portage_package.rb +33 -0
- data/lib/chef/resource/python.rb +33 -0
- data/lib/chef/resource/remote_directory.rb +91 -0
- data/lib/chef/resource/remote_file.rb +60 -0
- data/lib/chef/resource/route.rb +135 -0
- data/lib/chef/resource/ruby.rb +33 -0
- data/lib/chef/resource/ruby_block.rb +39 -0
- data/lib/chef/resource/scm.rb +137 -0
- data/lib/chef/resource/script.rb +51 -0
- data/lib/chef/resource/service.rb +134 -0
- data/lib/chef/resource/subversion.rb +34 -0
- data/lib/chef/resource/template.rb +60 -0
- data/lib/chef/resource/timestamped_deploy.rb +31 -0
- data/lib/chef/resource/user.rb +101 -0
- data/lib/chef/resource_collection.rb +212 -0
- data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
- data/lib/chef/resource_definition.rb +67 -0
- data/lib/chef/rest.rb +298 -0
- data/lib/chef/role.rb +301 -0
- data/lib/chef/run_list.rb +164 -0
- data/lib/chef/runner.rb +130 -0
- data/lib/chef/search/query.rb +71 -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 +185 -0
- data/lib/chef/tasks/chef_repo.rake +245 -0
- data/lib/chef/util/file_edit.rb +125 -0
- data/lib/chef/util/fileedit.rb +121 -0
- data/lib/chef/webui_user.rb +231 -0
- metadata +398 -0
|
@@ -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
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@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/mixin/from_file'
|
|
20
|
+
require 'chef/mixin/params_validate'
|
|
21
|
+
|
|
22
|
+
class Chef
|
|
23
|
+
class ResourceDefinition
|
|
24
|
+
|
|
25
|
+
include Chef::Mixin::FromFile
|
|
26
|
+
include Chef::Mixin::ParamsValidate
|
|
27
|
+
|
|
28
|
+
attr_accessor :name, :params, :recipe, :node
|
|
29
|
+
|
|
30
|
+
def initialize(node=nil)
|
|
31
|
+
@name = nil
|
|
32
|
+
@params = Hash.new
|
|
33
|
+
@recipe = nil
|
|
34
|
+
@node = node
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def define(resource_name, prototype_params=nil, &block)
|
|
38
|
+
unless resource_name.kind_of?(Symbol)
|
|
39
|
+
raise ArgumentError, "You must use a symbol when defining a new resource!"
|
|
40
|
+
end
|
|
41
|
+
@name = resource_name
|
|
42
|
+
if prototype_params
|
|
43
|
+
unless prototype_params.kind_of?(Hash)
|
|
44
|
+
raise ArgumentError, "You must pass a hash as the prototype parameters for a definition."
|
|
45
|
+
end
|
|
46
|
+
@params = prototype_params
|
|
47
|
+
end
|
|
48
|
+
if Kernel.block_given?
|
|
49
|
+
@recipe = block
|
|
50
|
+
else
|
|
51
|
+
raise ArgumentError, "You must pass a block to a definition."
|
|
52
|
+
end
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# When we do the resource definition, we're really just setting new values for
|
|
57
|
+
# the paramaters we prototyped at the top. This method missing is as simple as
|
|
58
|
+
# it gets.
|
|
59
|
+
def method_missing(symbol, *args)
|
|
60
|
+
@params[symbol] = args.length == 1 ? args[0] : args
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_s
|
|
64
|
+
"#{name.to_s}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
data/lib/chef/rest.rb
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
|
3
|
+
# Author:: Thom May (<thom@clearairturbulence.org>)
|
|
4
|
+
# Author:: Nuo Yan (<nuo@opscode.com>)
|
|
5
|
+
# Copyright:: Copyright (c) 2009 Opscode, Inc.
|
|
6
|
+
# License:: Apache License, Version 2.0
|
|
7
|
+
#
|
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
# you may not use this file except in compliance with the License.
|
|
10
|
+
# You may obtain a copy of the License at
|
|
11
|
+
#
|
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
#
|
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
# See the License for the specific language governing permissions and
|
|
18
|
+
# limitations under the License.
|
|
19
|
+
#
|
|
20
|
+
|
|
21
|
+
require 'chef/mixin/params_validate'
|
|
22
|
+
require 'chef/openid_registration'
|
|
23
|
+
require 'net/https'
|
|
24
|
+
require 'uri'
|
|
25
|
+
require 'json'
|
|
26
|
+
require 'tempfile'
|
|
27
|
+
require 'singleton'
|
|
28
|
+
require 'mixlib/authentication/signedheaderauth'
|
|
29
|
+
require 'chef/api_client'
|
|
30
|
+
|
|
31
|
+
include Mixlib::Authentication::SignedHeaderAuth
|
|
32
|
+
|
|
33
|
+
class Chef
|
|
34
|
+
class REST
|
|
35
|
+
|
|
36
|
+
class CookieJar < Hash
|
|
37
|
+
include Singleton
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
attr_accessor :url, :cookies, :client_name, :signing_key, :signing_key_filename, :sign_on_redirect, :sign_request
|
|
41
|
+
|
|
42
|
+
def initialize(url, client_name=Chef::Config[:node_name], signing_key_filename=Chef::Config[:client_key])
|
|
43
|
+
@url = url
|
|
44
|
+
@cookies = CookieJar.instance
|
|
45
|
+
@client_name = client_name
|
|
46
|
+
if signing_key_filename
|
|
47
|
+
@signing_key_filename = signing_key_filename
|
|
48
|
+
@signing_key = load_signing_key(signing_key_filename)
|
|
49
|
+
@sign_request = true
|
|
50
|
+
else
|
|
51
|
+
@signing_key = nil
|
|
52
|
+
@sign_request = false
|
|
53
|
+
end
|
|
54
|
+
@sign_on_redirect = true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def load_signing_key(key)
|
|
58
|
+
if File.exists?(key) && File.readable?(key)
|
|
59
|
+
IO.read(key)
|
|
60
|
+
else
|
|
61
|
+
raise Chef::Exceptions::PrivateKeyMissing, "I cannot find #{key}, which you told me to use to sign requests!"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Register the client
|
|
66
|
+
def register(name=Chef::Config[:node_name], destination=Chef::Config[:client_key])
|
|
67
|
+
|
|
68
|
+
if File.exists?(destination)
|
|
69
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination} - check permissions?" unless File.writable?(destination)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
nc = Chef::ApiClient.new
|
|
73
|
+
nc.name(name)
|
|
74
|
+
response = nc.save(true, true)
|
|
75
|
+
|
|
76
|
+
Chef::Log.debug("Registration response: #{response.inspect}")
|
|
77
|
+
|
|
78
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "The response from the server did not include a private key!" unless response.has_key?("private_key")
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
# Write out the private key
|
|
82
|
+
file = File.open(destination, "w")
|
|
83
|
+
file.print(response["private_key"])
|
|
84
|
+
file.close
|
|
85
|
+
rescue
|
|
86
|
+
raise Chef::Exceptions::CannotWritePrivateKey, "I cannot write your private key to #{destination}"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Send an HTTP GET request to the path
|
|
93
|
+
#
|
|
94
|
+
# === Parameters
|
|
95
|
+
# path:: The path to GET
|
|
96
|
+
# raw:: Whether you want the raw body returned, or JSON inflated. Defaults
|
|
97
|
+
# to JSON inflated.
|
|
98
|
+
def get_rest(path, raw=false, headers={})
|
|
99
|
+
run_request(:GET, create_url(path), headers, false, 10, raw)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Send an HTTP DELETE request to the path
|
|
103
|
+
def delete_rest(path, headers={})
|
|
104
|
+
run_request(:DELETE, create_url(path), headers)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Send an HTTP POST request to the path
|
|
108
|
+
def post_rest(path, json, headers={})
|
|
109
|
+
run_request(:POST, create_url(path), headers, json)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Send an HTTP PUT request to the path
|
|
113
|
+
def put_rest(path, json, headers={})
|
|
114
|
+
run_request(:PUT, create_url(path), headers, json)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def create_url(path)
|
|
118
|
+
if path =~ /^(http|https):\/\//
|
|
119
|
+
URI.parse(path)
|
|
120
|
+
else
|
|
121
|
+
URI.parse("#{@url}/#{path}")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def sign_request(http_method, private_key, user_id, body = "", host="localhost")
|
|
126
|
+
#body = "" if body == false
|
|
127
|
+
timestamp = Time.now.utc.iso8601
|
|
128
|
+
sign_obj = Mixlib::Authentication::SignedHeaderAuth.signing_object(
|
|
129
|
+
:http_method=>http_method,
|
|
130
|
+
:body=>body,
|
|
131
|
+
:user_id=>user_id,
|
|
132
|
+
:timestamp=>timestamp)
|
|
133
|
+
signed = sign_obj.sign(private_key).merge({:host => host})
|
|
134
|
+
signed.inject({}){|memo, kv| memo["#{kv[0].to_s.upcase}"] = kv[1];memo}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Actually run an HTTP request. First argument is the HTTP method,
|
|
138
|
+
# which should be one of :GET, :PUT, :POST or :DELETE. Next is the
|
|
139
|
+
# URL, then an object to include in the body (which will be converted with
|
|
140
|
+
# .to_json) and finally, the limit of HTTP Redirects to follow (10).
|
|
141
|
+
#
|
|
142
|
+
# Typically, you won't use this method -- instead, you'll use one of
|
|
143
|
+
# the helper methods (get_rest, post_rest, etc.)
|
|
144
|
+
#
|
|
145
|
+
# Will return the body of the response on success.
|
|
146
|
+
def run_request(method, url, headers={}, data=false, limit=10, raw=false)
|
|
147
|
+
|
|
148
|
+
http_retry_delay = Chef::Config[:http_retry_delay]
|
|
149
|
+
http_retry_count = Chef::Config[:http_retry_count]
|
|
150
|
+
|
|
151
|
+
raise ArgumentError, 'HTTP redirect too deep' if limit == 0
|
|
152
|
+
|
|
153
|
+
http = Net::HTTP.new(url.host, url.port)
|
|
154
|
+
if url.scheme == "https"
|
|
155
|
+
http.use_ssl = true
|
|
156
|
+
if Chef::Config[:ssl_verify_mode] == :verify_none
|
|
157
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
158
|
+
elsif Chef::Config[:ssl_verify_mode] == :verify_peer
|
|
159
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
160
|
+
end
|
|
161
|
+
if Chef::Config[:ssl_ca_path] and File.exists?(Chef::Config[:ssl_ca_path])
|
|
162
|
+
http.ca_path = Chef::Config[:ssl_ca_path]
|
|
163
|
+
elsif Chef::Config[:ssl_ca_file] and File.exists?(Chef::Config[:ssl_ca_file])
|
|
164
|
+
http.ca_file = Chef::Config[:ssl_ca_file]
|
|
165
|
+
end
|
|
166
|
+
if Chef::Config[:ssl_client_cert] && File.exists?(Chef::Config[:ssl_client_cert])
|
|
167
|
+
http.cert = OpenSSL::X509::Certificate.new(File.read(Chef::Config[:ssl_client_cert]))
|
|
168
|
+
http.key = OpenSSL::PKey::RSA.new(File.read(Chef::Config[:ssl_client_key]))
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
http.read_timeout = Chef::Config[:rest_timeout]
|
|
173
|
+
|
|
174
|
+
unless raw
|
|
175
|
+
headers = headers.merge({
|
|
176
|
+
'Accept' => "application/json",
|
|
177
|
+
})
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
if @cookies.has_key?("#{url.host}:#{url.port}")
|
|
181
|
+
headers['Cookie'] = @cookies["#{url.host}:#{url.port}"]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
json_body = data ? data.to_json : nil
|
|
185
|
+
|
|
186
|
+
if @sign_request
|
|
187
|
+
Chef::Log.debug("Signing the request as #{@client_name}")
|
|
188
|
+
if json_body
|
|
189
|
+
headers.merge!(sign_request(method, OpenSSL::PKey::RSA.new(@signing_key), @client_name, json_body, "#{url.host}:#{url.port}"))
|
|
190
|
+
else
|
|
191
|
+
headers.merge!(sign_request(method, OpenSSL::PKey::RSA.new(@signing_key), @client_name, "", "#{url.host}:#{url.port}"))
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
req = nil
|
|
196
|
+
case method
|
|
197
|
+
when :GET
|
|
198
|
+
req_path = "#{url.path}"
|
|
199
|
+
req_path << "?#{url.query}" if url.query
|
|
200
|
+
req = Net::HTTP::Get.new(req_path, headers)
|
|
201
|
+
when :POST
|
|
202
|
+
headers["Content-Type"] = 'application/json' if data
|
|
203
|
+
req_path = "#{url.path}"
|
|
204
|
+
req_path << "?#{url.query}" if url.query
|
|
205
|
+
req = Net::HTTP::Post.new(req_path, headers)
|
|
206
|
+
req.body = json_body if json_body
|
|
207
|
+
when :PUT
|
|
208
|
+
headers["Content-Type"] = 'application/json' if data
|
|
209
|
+
req_path = "#{url.path}"
|
|
210
|
+
req_path << "?#{url.query}" if url.query
|
|
211
|
+
req = Net::HTTP::Put.new(req_path, headers)
|
|
212
|
+
req.body = json_body if json_body
|
|
213
|
+
when :DELETE
|
|
214
|
+
req_path = "#{url.path}"
|
|
215
|
+
req_path << "?#{url.query}" if url.query
|
|
216
|
+
req = Net::HTTP::Delete.new(req_path, headers)
|
|
217
|
+
else
|
|
218
|
+
raise ArgumentError, "You must provide :GET, :PUT, :POST or :DELETE as the method"
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
Chef::Log.debug("Sending HTTP Request via #{req.method} to #{url.host}:#{url.port}#{req.path}")
|
|
222
|
+
|
|
223
|
+
# Optionally handle HTTP Basic Authentication
|
|
224
|
+
req.basic_auth(url.user, url.password) if url.user
|
|
225
|
+
|
|
226
|
+
res = nil
|
|
227
|
+
tf = nil
|
|
228
|
+
http_retries = 1
|
|
229
|
+
|
|
230
|
+
begin
|
|
231
|
+
res = http.request(req) do |response|
|
|
232
|
+
if raw
|
|
233
|
+
tf = Tempfile.new("chef-rest")
|
|
234
|
+
# Stolen from http://www.ruby-forum.com/topic/166423
|
|
235
|
+
# Kudos to _why!
|
|
236
|
+
size, total = 0, response.header['Content-Length'].to_i
|
|
237
|
+
response.read_body do |chunk|
|
|
238
|
+
tf.write(chunk)
|
|
239
|
+
size += chunk.size
|
|
240
|
+
if size == 0
|
|
241
|
+
Chef::Log.debug("#{req.path} done (0 length file)")
|
|
242
|
+
elsif total == 0
|
|
243
|
+
Chef::Log.debug("#{req.path} (zero content length)")
|
|
244
|
+
else
|
|
245
|
+
Chef::Log.debug("#{req.path}" + " %d%% done (%d of %d)" % [(size * 100) / total, size, total])
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
tf.close
|
|
249
|
+
tf
|
|
250
|
+
else
|
|
251
|
+
response.read_body
|
|
252
|
+
end
|
|
253
|
+
response
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
rescue Errno::ECONNREFUSED => e
|
|
257
|
+
Chef::Log.error("Connection refused connecting to #{url.host}:#{url.port} for #{req.path} #{http_retries}/#{http_retry_count}")
|
|
258
|
+
sleep(http_retry_delay)
|
|
259
|
+
retry if (http_retries += 1) < http_retry_count
|
|
260
|
+
raise Errno::ECONNREFUSED, "Connection refused connecting to #{url.host}:#{url.port} for #{req.path}, giving up"
|
|
261
|
+
rescue Timeout::Error
|
|
262
|
+
Chef::Log.error("Timeout connecting to #{url.host}:#{url.port} for #{req.path}, retry #{http_retries}/#{http_retry_count}")
|
|
263
|
+
sleep(http_retry_delay)
|
|
264
|
+
retry if (http_retries += 1) < http_retry_count
|
|
265
|
+
raise Timeout::Error, "Timeout connecting to #{url.host}:#{url.port} for #{req.path}, giving up"
|
|
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.warn("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
|
+
end
|
|
296
|
+
|
|
297
|
+
end
|
|
298
|
+
end
|