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.

Files changed (180) hide show
  1. data/README.rdoc +11 -10
  2. data/bin/chef-client +2 -2
  3. data/bin/chef-solo +1 -1
  4. data/bin/knife +27 -0
  5. data/bin/shef +49 -0
  6. data/distro/README +2 -0
  7. data/distro/{debian → common}/man/man1/chef-indexer.1 +0 -0
  8. data/distro/{debian → common}/man/man1/chef-server.1 +0 -0
  9. data/distro/{debian → common}/man/man8/chef-client.8 +0 -0
  10. data/distro/{debian → common}/man/man8/chef-solo.8 +0 -0
  11. data/distro/common/man/man8/knife.8 +375 -0
  12. data/distro/redhat/etc/init.d/chef-client +8 -4
  13. data/distro/redhat/etc/init.d/chef-server +16 -15
  14. data/distro/redhat/etc/init.d/chef-server-webui +78 -0
  15. data/distro/redhat/etc/init.d/chef-solr +76 -0
  16. data/distro/redhat/etc/init.d/chef-solr-indexer +75 -0
  17. data/distro/redhat/etc/sysconfig/chef-client +10 -0
  18. data/distro/redhat/etc/sysconfig/chef-server +10 -0
  19. data/distro/redhat/etc/sysconfig/chef-server-webui +10 -0
  20. data/distro/redhat/etc/sysconfig/chef-solr +9 -0
  21. data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
  22. data/distro/suse/etc/init.d/chef-client +121 -0
  23. data/lib/chef.rb +1 -1
  24. data/lib/chef/api_client.rb +263 -0
  25. data/lib/chef/application.rb +1 -1
  26. data/lib/chef/application/client.rb +21 -3
  27. data/lib/chef/application/knife.rb +144 -0
  28. data/lib/chef/application/server.rb +2 -1
  29. data/lib/chef/application/solo.rb +9 -2
  30. data/lib/chef/cache.rb +61 -0
  31. data/lib/chef/cache/checksum.rb +70 -0
  32. data/lib/chef/certificate.rb +154 -0
  33. data/lib/chef/client.rb +123 -220
  34. data/lib/chef/compile.rb +9 -21
  35. data/lib/chef/config.rb +67 -10
  36. data/lib/chef/cookbook.rb +49 -22
  37. data/lib/chef/cookbook/metadata.rb +85 -5
  38. data/lib/chef/cookbook_loader.rb +4 -4
  39. data/lib/chef/couchdb.rb +99 -30
  40. data/lib/chef/daemon.rb +1 -1
  41. data/lib/chef/data_bag.rb +215 -0
  42. data/lib/chef/data_bag_item.rb +219 -0
  43. data/lib/chef/exceptions.rb +3 -0
  44. data/lib/chef/index_queue.rb +29 -0
  45. data/lib/chef/index_queue/amqp_client.rb +106 -0
  46. data/lib/chef/index_queue/consumer.rb +76 -0
  47. data/lib/chef/index_queue/indexable.rb +74 -0
  48. data/lib/chef/knife.rb +309 -0
  49. data/lib/chef/knife/client_bulk_delete.rb +40 -0
  50. data/lib/chef/knife/client_create.rb +62 -0
  51. data/lib/chef/knife/client_delete.rb +37 -0
  52. data/lib/chef/knife/client_edit.rb +37 -0
  53. data/lib/chef/knife/client_list.rb +40 -0
  54. data/lib/chef/knife/client_reregister.rb +48 -0
  55. data/lib/chef/knife/client_show.rb +42 -0
  56. data/lib/chef/knife/configure.rb +123 -0
  57. data/lib/chef/knife/cookbook_bulk_delete.rb +46 -0
  58. data/lib/chef/knife/cookbook_delete.rb +41 -0
  59. data/lib/chef/knife/cookbook_download.rb +57 -0
  60. data/lib/chef/knife/cookbook_list.rb +41 -0
  61. data/lib/chef/knife/cookbook_metadata.rb +87 -0
  62. data/lib/chef/knife/cookbook_show.rb +75 -0
  63. data/lib/chef/knife/cookbook_upload.rb +179 -0
  64. data/lib/chef/knife/data_bag_create.rb +43 -0
  65. data/lib/chef/knife/data_bag_delete.rb +43 -0
  66. data/lib/chef/knife/data_bag_edit.rb +49 -0
  67. data/lib/chef/knife/data_bag_list.rb +42 -0
  68. data/lib/chef/knife/data_bag_show.rb +40 -0
  69. data/lib/chef/knife/ec2_instance_data.rb +46 -0
  70. data/lib/chef/knife/index_rebuild.rb +51 -0
  71. data/lib/chef/knife/node_bulk_delete.rb +43 -0
  72. data/lib/chef/knife/node_create.rb +39 -0
  73. data/lib/chef/knife/node_delete.rb +36 -0
  74. data/lib/chef/knife/node_edit.rb +36 -0
  75. data/lib/chef/knife/node_from_file.rb +42 -0
  76. data/lib/chef/knife/node_list.rb +41 -0
  77. data/lib/chef/knife/node_run_list_add.rb +64 -0
  78. data/lib/chef/knife/node_run_list_remove.rb +45 -0
  79. data/lib/chef/knife/node_show.rb +46 -0
  80. data/lib/chef/knife/role_bulk_delete.rb +44 -0
  81. data/lib/chef/knife/role_create.rb +44 -0
  82. data/lib/chef/knife/role_delete.rb +36 -0
  83. data/lib/chef/knife/role_edit.rb +37 -0
  84. data/lib/chef/knife/role_from_file.rb +46 -0
  85. data/lib/chef/knife/role_list.rb +40 -0
  86. data/lib/chef/knife/role_show.rb +43 -0
  87. data/lib/chef/knife/search.rb +94 -0
  88. data/lib/chef/knife/ssh.rb +170 -0
  89. data/lib/chef/log.rb +30 -8
  90. data/lib/chef/mixin/checksum.rb +2 -7
  91. data/lib/chef/mixin/command.rb +32 -13
  92. data/lib/chef/mixin/convert_to_class_name.rb +15 -0
  93. data/lib/chef/mixin/deep_merge.rb +199 -11
  94. data/lib/chef/mixin/generate_url.rb +18 -9
  95. data/lib/chef/mixin/language.rb +29 -1
  96. data/lib/chef/mixin/language_include_attribute.rb +56 -0
  97. data/lib/chef/mixin/language_include_recipe.rb +53 -0
  98. data/lib/chef/mixin/params_validate.rb +25 -12
  99. data/lib/chef/mixin/recipe_definition_dsl_core.rb +2 -0
  100. data/lib/chef/mixin/template.rb +11 -1
  101. data/lib/chef/mixin/xml_escape.rb +87 -0
  102. data/lib/chef/node.rb +144 -122
  103. data/lib/chef/openid_registration.rb +12 -5
  104. data/lib/chef/platform.rb +89 -47
  105. data/lib/chef/provider/breakpoint.rb +36 -0
  106. data/lib/chef/provider/cron.rb +5 -6
  107. data/lib/chef/provider/deploy.rb +43 -10
  108. data/lib/chef/provider/deploy/revision.rb +2 -3
  109. data/lib/chef/provider/erl_call.rb +72 -0
  110. data/lib/chef/provider/file.rb +8 -4
  111. data/lib/chef/provider/git.rb +10 -5
  112. data/lib/chef/provider/group/dscl.rb +128 -0
  113. data/lib/chef/provider/http_request.rb +6 -2
  114. data/lib/chef/provider/ifconfig.rb +1 -0
  115. data/lib/chef/provider/link.rb +1 -1
  116. data/lib/chef/provider/log.rb +53 -0
  117. data/lib/chef/provider/mdadm.rb +88 -0
  118. data/lib/chef/provider/mount/mount.rb +1 -1
  119. data/lib/chef/provider/package.rb +1 -1
  120. data/lib/chef/provider/package/easy_install.rb +106 -0
  121. data/lib/chef/provider/package/pacman.rb +101 -0
  122. data/lib/chef/provider/package/portage.rb +1 -1
  123. data/lib/chef/provider/package/rpm.rb +10 -8
  124. data/lib/chef/provider/package/yum-dump.py +22 -3
  125. data/lib/chef/provider/package/yum.rb +32 -8
  126. data/lib/chef/provider/package/zypper.rb +132 -0
  127. data/lib/chef/provider/remote_directory.rb +58 -49
  128. data/lib/chef/provider/remote_file.rb +1 -1
  129. data/lib/chef/provider/route.rb +136 -80
  130. data/lib/chef/provider/ruby_block.rb +18 -1
  131. data/lib/chef/provider/service/arch.rb +109 -0
  132. data/lib/chef/provider/service/freebsd.rb +0 -1
  133. data/lib/chef/provider/service/simple.rb +2 -3
  134. data/lib/chef/provider/service/upstart.rb +191 -0
  135. data/lib/chef/provider/subversion.rb +12 -4
  136. data/lib/chef/provider/template.rb +85 -53
  137. data/lib/chef/provider/user.rb +1 -1
  138. data/lib/chef/provider/user/dscl.rb +277 -0
  139. data/lib/chef/provider/user/useradd.rb +1 -0
  140. data/lib/chef/recipe.rb +2 -41
  141. data/lib/chef/resource.rb +9 -3
  142. data/lib/chef/resource/breakpoint.rb +35 -0
  143. data/lib/chef/resource/deploy.rb +16 -2
  144. data/lib/chef/resource/easy_install_package.rb +41 -0
  145. data/lib/chef/resource/erl_call.rb +83 -0
  146. data/lib/chef/resource/freebsd_package.rb +35 -0
  147. data/lib/chef/resource/log.rb +62 -0
  148. data/lib/chef/resource/mdadm.rb +82 -0
  149. data/lib/chef/resource/pacman_package.rb +33 -0
  150. data/lib/chef/resource/ruby_block.rb +21 -2
  151. data/lib/chef/resource/scm.rb +8 -0
  152. data/lib/chef/resource/subversion.rb +1 -0
  153. data/lib/chef/resource/user.rb +5 -2
  154. data/lib/chef/resource/yum_package.rb +36 -0
  155. data/lib/chef/resource_collection.rb +17 -9
  156. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  157. data/lib/chef/rest.rb +166 -81
  158. data/lib/chef/role.rb +114 -38
  159. data/lib/chef/run_list.rb +15 -6
  160. data/lib/chef/runner.rb +13 -11
  161. data/lib/chef/search/query.rb +60 -0
  162. data/lib/chef/shef.rb +220 -0
  163. data/lib/chef/shef/ext.rb +297 -0
  164. data/lib/chef/shef/shef_session.rb +175 -0
  165. data/lib/chef/streaming_cookbook_uploader.rb +187 -0
  166. data/lib/chef/tasks/chef_repo.rake +53 -155
  167. data/lib/chef/util/file_edit.rb +94 -96
  168. data/lib/chef/webui_user.rb +233 -0
  169. metadata +219 -63
  170. data/distro/debian/etc/init.d/chef-indexer +0 -175
  171. data/distro/redhat/etc/chef/client.rb +0 -16
  172. data/distro/redhat/etc/chef/indexer.rb +0 -10
  173. data/distro/redhat/etc/chef/server.rb +0 -22
  174. data/distro/redhat/etc/init.d/chef-indexer +0 -76
  175. data/lib/chef/application/indexer.rb +0 -141
  176. data/lib/chef/queue.rb +0 -145
  177. data/lib/chef/search.rb +0 -88
  178. data/lib/chef/search/result.rb +0 -64
  179. data/lib/chef/search_index.rb +0 -77
  180. data/lib/chef/util/fileedit.rb +0 -121
@@ -0,0 +1,219 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Nuo Yan (<nuo@opscode.com>)
4
+ # Author:: Christopher Brown (<cb@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/config'
22
+ require 'chef/mixin/params_validate'
23
+ require 'chef/mixin/from_file'
24
+ require 'chef/couchdb'
25
+ require 'chef/data_bag_item'
26
+ require 'extlib'
27
+ require 'json'
28
+
29
+ class Chef
30
+ class DataBagItem
31
+
32
+ include Chef::Mixin::FromFile
33
+ include Chef::Mixin::ParamsValidate
34
+ include Chef::IndexQueue::Indexable
35
+
36
+ DESIGN_DOCUMENT = {
37
+ "version" => 1,
38
+ "language" => "javascript",
39
+ "views" => {
40
+ "all" => {
41
+ "map" => <<-EOJS
42
+ function(doc) {
43
+ if (doc.chef_type == "data_bag_item") {
44
+ emit(doc.name, doc);
45
+ }
46
+ }
47
+ EOJS
48
+ },
49
+ "all_id" => {
50
+ "map" => <<-EOJS
51
+ function(doc) {
52
+ if (doc.chef_type == "data_bag_item") {
53
+ emit(doc.name, doc.name);
54
+ }
55
+ }
56
+ EOJS
57
+ }
58
+ }
59
+ }
60
+
61
+ attr_accessor :couchdb_rev, :couchdb_id, :couchdb
62
+ attr_reader :raw_data
63
+
64
+ # Create a new Chef::DataBagItem
65
+ def initialize(couchdb=nil)
66
+ @couchdb_rev = nil
67
+ @couchdb_id = nil
68
+ @data_bag = nil
69
+ @raw_data = Mash.new
70
+ @couchdb = couchdb || Chef::CouchDB.new
71
+ end
72
+
73
+ def chef_server_rest
74
+ Chef::REST.new(Chef::Config[:chef_server_url])
75
+ end
76
+
77
+ def self.chef_server_rest
78
+ Chef::REST.new(Chef::Config[:chef_server_url])
79
+ end
80
+
81
+ def raw_data
82
+ @raw_data
83
+ end
84
+
85
+ def raw_data=(new_data)
86
+ raise ArgumentError, "Data Bag Items must contain a Hash or Mash!" unless new_data.kind_of?(Hash) || new_data.kind_of?(Mash)
87
+ raise ArgumentError, "Data Bag Items must have an id key in the hash! #{new_data.inspect}" unless new_data.has_key?("id")
88
+ raise ArgumentError, "Data Bag Item id does not match alphanumeric/-/_!" unless new_data["id"] =~ /^[\-[:alnum:]_]+$/
89
+ @raw_data = new_data
90
+ end
91
+
92
+ def data_bag(arg=nil)
93
+ set_or_return(
94
+ :data_bag,
95
+ arg,
96
+ :regex => /^[\-[:alnum:]_]+$/
97
+ )
98
+ end
99
+
100
+ def name
101
+ object_name
102
+ end
103
+
104
+ def object_name
105
+ raise ArgumentError, "You must have an 'id' or :id key in the raw data" unless raw_data.has_key?('id')
106
+ raise ArgumentError, "You must have declared what bag this item belongs to!" unless data_bag
107
+
108
+ id = raw_data['id']
109
+ "data_bag_item_#{data_bag}_#{id}"
110
+ end
111
+
112
+ def self.object_name(data_bag_name, id)
113
+ "data_bag_item_#{data_bag_name}_#{id}"
114
+ end
115
+
116
+ def to_hash
117
+ result = self.raw_data
118
+ result["chef_type"] = "data_bag_item"
119
+ result["data_bag"] = self.data_bag
120
+ result["_rev"] = @couchdb_rev if @couchdb_rev
121
+ result
122
+ end
123
+
124
+ # Serialize this object as a hash
125
+ def to_json(*a)
126
+ result = {
127
+ "name" => self.object_name,
128
+ "json_class" => self.class.name,
129
+ "chef_type" => "data_bag_item",
130
+ "data_bag" => self.data_bag,
131
+ "raw_data" => self.raw_data
132
+ }
133
+ result["_rev"] = @couchdb_rev if @couchdb_rev
134
+ result.to_json(*a)
135
+ end
136
+
137
+ # Create a Chef::DataBagItem from JSON
138
+ def self.json_create(o)
139
+ bag_item = new
140
+ bag_item.data_bag(o["data_bag"])
141
+ o.delete("data_bag")
142
+ o.delete("chef_type")
143
+ o.delete("json_class")
144
+ o.delete("name")
145
+ if o.has_key?("_rev")
146
+ bag_item.couchdb_rev = o["_rev"]
147
+ o.delete("_rev")
148
+ end
149
+ if o.has_key?("_id")
150
+ bag_item.couchdb_id = o["_id"]
151
+ bag_item.index_id = bag_item.couchdb_id
152
+ o.delete("_id")
153
+ end
154
+ bag_item.raw_data = Mash.new(o["raw_data"])
155
+ bag_item
156
+ end
157
+
158
+ # The Data Bag Item behaves like a hash - we pass all that stuff along to @raw_data.
159
+ def method_missing(method_symbol, *args, &block)
160
+ self.raw_data.send(method_symbol, *args, &block)
161
+ end
162
+
163
+ # Load a Data Bag Item by name from CouchDB
164
+ def self.cdb_load(data_bag, name, couchdb=nil)
165
+ (couchdb || Chef::CouchDB.new).load("data_bag_item", object_name(data_bag, name))
166
+ end
167
+
168
+ # Load a Data Bag Item by name via RESTful API
169
+ def self.load(data_bag, name)
170
+ Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("data/#{data_bag}/#{name}")
171
+ end
172
+
173
+ # Remove this Data Bag Item from CouchDB
174
+ def cdb_destroy
175
+ Chef::Log.debug "destroying data bag item: #{self.inspect}"
176
+ @couchdb.delete("data_bag_item", object_name, @couchdb_rev)
177
+ end
178
+
179
+ def destroy(data_bag=data_bag, databag_item=name)
180
+ chef_server_rest.delete_rest("data/#{data_bag}/#{databag_item}")
181
+ end
182
+
183
+ # Save this Data Bag Item to CouchDB
184
+ def cdb_save
185
+ @couchdb_rev = @couchdb.store("data_bag_item", object_name, self)["rev"]
186
+ end
187
+
188
+ # Save this Data Bag Item via RESTful API
189
+ def save(item_id=@raw_data['id'])
190
+ r = chef_server_rest
191
+ begin
192
+ r.put_rest("data/#{data_bag}/#{item_id}", @raw_data)
193
+ rescue Net::HTTPServerException => e
194
+ raise e unless e.response.code == "404"
195
+ r.post_rest("data/#{data_bag}", @raw_data)
196
+ end
197
+ self
198
+ end
199
+
200
+ # Create this Data Bag Item via RESTful API
201
+ def create
202
+ chef_server_rest.post_rest("data/#{data_bag}", @raw_data)
203
+ self
204
+ end
205
+
206
+ # Set up our CouchDB design document
207
+ def self.create_design_document(couchdb=nil)
208
+ (couchdb || Chef::CouchDB.new).create_design_document("data_bag_items", DESIGN_DOCUMENT)
209
+ end
210
+
211
+ # As a string
212
+ def to_s
213
+ "data_bag_item[#{@name}]"
214
+ end
215
+
216
+ end
217
+ end
218
+
219
+
@@ -32,5 +32,8 @@ class Chef
32
32
  class Group < RuntimeError; end
33
33
  class Link < RuntimeError; end
34
34
  class Mount < RuntimeError; end
35
+ class CouchDBNotFound < RuntimeError; end
36
+ class PrivateKeyMissing < RuntimeError; end
37
+ class CannotWritePrivateKey < RuntimeError; end
35
38
  end
36
39
  end
@@ -0,0 +1,29 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
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 "singleton"
20
+ require "bunny"
21
+
22
+ require "chef/index_queue/amqp_client"
23
+ require "chef/index_queue/indexable"
24
+ require "chef/index_queue/consumer"
25
+
26
+ class Chef
27
+ module IndexQueue
28
+ end
29
+ end
@@ -0,0 +1,106 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
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
+ class Chef
20
+ module IndexQueue
21
+ class AmqpClient
22
+ include Singleton
23
+
24
+ def initialize
25
+ reset!
26
+ end
27
+
28
+ def reset!
29
+ @amqp_client && amqp_client.connected? && amqp_client.stop
30
+ @amqp_client = nil
31
+ @exchange = nil
32
+ @queue = nil
33
+ end
34
+
35
+ def stop
36
+ @queue && @queue.subscription && @queue.unsubscribe
37
+ @amqp_client && @amqp_client.stop
38
+ end
39
+
40
+ def amqp_client
41
+ unless @amqp_client
42
+ begin
43
+ @amqp_client = Bunny.new(amqp_opts)
44
+ Chef::Log.debug "Starting AMQP connection with client settings: #{@amqp_client.inspect}"
45
+ @amqp_client.start
46
+ @amqp_client.qos(:prefetch_count => 1)
47
+ rescue Bunny::ServerDownError => e
48
+ Chef::Log.fatal "Could not connect to rabbitmq. Is it running, reachable, and configured correctly?"
49
+ raise e
50
+ rescue Bunny::ProtocolError => e
51
+ Chef::Log.fatal "Connection to rabbitmq refused. Check your rabbitmq configuration and chef's amqp* settings"
52
+ raise e
53
+ end
54
+ end
55
+ @amqp_client
56
+ end
57
+
58
+ def exchange
59
+ @exchange ||= amqp_client.exchange("chef-indexer", :durable => true, :type => :fanout)
60
+ end
61
+
62
+ def queue
63
+ unless @queue
64
+ @queue = amqp_client.queue("chef-index-consumer-" + consumer_id, :durable => durable_queue?)
65
+ @queue.bind(exchange)
66
+ end
67
+ @queue
68
+ end
69
+
70
+ def disconnected!
71
+ @amqp_client = nil
72
+ reset!
73
+ end
74
+
75
+ def send_action(action, data)
76
+ begin
77
+ exchange.publish({"action" => action.to_s, "payload" => data}.to_json)
78
+ rescue Bunny::ServerDownError, Bunny::ConnectionError, Errno::ECONNRESET => e
79
+ Chef::Log.error("Disconnected from the AMQP Broker, cannot queue data to the indexer")
80
+ disconnected!
81
+ raise e
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def durable_queue?
88
+ !!Chef::Config[:amqp_consumer_id]
89
+ end
90
+
91
+ def consumer_id
92
+ Chef::Config[:amqp_consumer_id] || UUIDTools::UUID.random_create.to_s
93
+ end
94
+
95
+ def amqp_opts
96
+ { :spec => '08',
97
+ :host => Chef::Config[:amqp_host],
98
+ :port => Chef::Config[:amqp_port],
99
+ :user => Chef::Config[:amqp_user],
100
+ :pass => Chef::Config[:amqp_pass],
101
+ :vhost => Chef::Config[:amqp_vhost]}
102
+ end
103
+
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,76 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
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
+ class Chef
20
+ module IndexQueue
21
+ module Consumer
22
+ module ClassMethods
23
+ def expose(*methods)
24
+ @exposed_methods = Array(@exposed_methods)
25
+ @exposed_methods += methods
26
+ end
27
+
28
+ def exposed_methods
29
+ @exposed_methods || []
30
+ end
31
+
32
+ def whitelisted?(method_name)
33
+ exposed_methods.include?(method_name)
34
+ end
35
+ end
36
+
37
+ def self.included(including_class)
38
+ including_class.send(:extend, ClassMethods)
39
+ end
40
+
41
+ def run
42
+ Chef::Log.debug("Starting Index Queue Consumer")
43
+ AmqpClient.instance.queue # triggers connection setup
44
+
45
+ begin
46
+ AmqpClient.instance.queue.subscribe(:ack => true, :timeout => false) do |message|
47
+ call_action_for_message(message)
48
+ end
49
+ rescue Bunny::ConnectionError, Errno::ECONNRESET, Bunny::ServerDownError
50
+ AmqpClient.instance.disconnected!
51
+ Chef::Log.warn "Connection to rabbitmq lost. attempting to reconnect"
52
+ sleep 1
53
+ retry
54
+ end
55
+ end
56
+ alias :start :run
57
+
58
+ def call_action_for_message(message)
59
+ amqp_payload = JSON.parse(message[:payload])
60
+ action = amqp_payload["action"].to_sym
61
+ app_payload = amqp_payload["payload"]
62
+ assert_method_whitelisted(action)
63
+ send(action, app_payload)
64
+ end
65
+
66
+ private
67
+
68
+ def assert_method_whitelisted(method_name)
69
+ unless self.class.whitelisted?(method_name)
70
+ raise ArgumentError, "non-exposed method #{method_name} called via index queue"
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,74 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
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
+ class Chef
20
+ module IndexQueue
21
+ module Indexable
22
+
23
+ module ClassMethods
24
+
25
+ def index_object_type(explicit_type_name=nil)
26
+ @index_object_type = explicit_type_name.to_s if explicit_type_name
27
+ @index_object_type
28
+ end
29
+
30
+ # Resets all metadata used for indexing to nil. Used for testing
31
+ def reset_index_metadata!
32
+ @index_object_type = nil
33
+ end
34
+
35
+ end
36
+
37
+ def self.included(including_class)
38
+ including_class.send(:extend, ClassMethods)
39
+ end
40
+
41
+ attr_accessor :index_id
42
+
43
+ def index_object_type
44
+ self.class.index_object_type || Mixin::ConvertToClassName.snake_case_basename(self.class.name)
45
+ end
46
+
47
+ def with_indexer_metadata(with_metadata={})
48
+ # changing input param symbol keys to strings, as the keys in hash that goes to solr are expected to be strings [cb]
49
+ with_metadata.each do |key,value|
50
+ with_metadata[key.to_s] = with_metadata.delete(key)
51
+ end
52
+
53
+ with_metadata["type"] ||= self.index_object_type
54
+ with_metadata["id"] ||= self.index_id
55
+ with_metadata["database"] ||= Chef::Config[:couchdb_database]
56
+ with_metadata["item"] ||= self
57
+
58
+ raise ArgumentError, "Type, Id, or Database missing in index operation: #{with_metadata.inspect}" if (with_metadata["id"].nil? or with_metadata["type"].nil?)
59
+ with_metadata
60
+ end
61
+
62
+ def add_to_index(metadata={})
63
+ Chef::Log.debug("pushing item to index queue for addition: #{self.with_indexer_metadata(metadata)}")
64
+ AmqpClient.instance.send_action(:add, self.with_indexer_metadata(metadata))
65
+ end
66
+
67
+ def delete_from_index(metadata={})
68
+ Chef::Log.debug("pushing item to index queue for deletion: #{self.with_indexer_metadata(metadata)}")
69
+ AmqpClient.instance.send_action(:delete, self.with_indexer_metadata(metadata))
70
+ end
71
+
72
+ end
73
+ end
74
+ end