chef-zero 1.0.1 → 1.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.
Files changed (33) hide show
  1. data/lib/chef_zero/cookbook_data.rb +58 -24
  2. data/lib/chef_zero/data_normalizer.rb +1 -1
  3. data/lib/chef_zero/data_store/chef_fs_store.rb +96 -0
  4. data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -0
  5. data/lib/chef_zero/data_store/data_error.rb +31 -0
  6. data/lib/chef_zero/data_store/data_not_found_error.rb +29 -0
  7. data/lib/chef_zero/data_store/memory_store.rb +164 -0
  8. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +6 -2
  9. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +4 -4
  10. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +16 -12
  11. data/lib/chef_zero/endpoints/cookbooks_base.rb +10 -1
  12. data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +1 -1
  13. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +1 -6
  14. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +2 -3
  15. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +2 -2
  16. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +13 -19
  17. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +1 -1
  18. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +2 -2
  19. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +2 -2
  20. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +1 -0
  21. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +1 -1
  22. data/lib/chef_zero/endpoints/principal_endpoint.rb +2 -2
  23. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +2 -5
  24. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +9 -13
  25. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +4 -6
  26. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +11 -4
  27. data/lib/chef_zero/endpoints/search_endpoint.rb +7 -9
  28. data/lib/chef_zero/endpoints/searches_endpoint.rb +1 -1
  29. data/lib/chef_zero/rest_base.rb +67 -9
  30. data/lib/chef_zero/rest_router.rb +5 -1
  31. data/lib/chef_zero/server.rb +15 -28
  32. data/lib/chef_zero/version.rb +1 -1
  33. metadata +7 -2
@@ -16,24 +16,31 @@ module ChefZero
16
16
  needed_checksums = JSON.parse(request.body, :create_additions => false)['checksums']
17
17
  result_checksums = {}
18
18
  needed_checksums.keys.each do |needed_checksum|
19
- if data['file_store'].has_key?(needed_checksum)
19
+ if list_data(request, ['file_store', 'checksums']).include?(needed_checksum)
20
20
  result_checksums[needed_checksum] = { :needs_upload => false }
21
21
  else
22
22
  result_checksums[needed_checksum] = {
23
23
  :needs_upload => true,
24
- :url => build_uri(request.base_uri, ['file_store', needed_checksum])
24
+ :url => build_uri(request.base_uri, ['file_store', 'checksums', needed_checksum])
25
25
  }
26
26
  sandbox_checksums << needed_checksum
27
27
  end
28
28
  end
29
29
 
30
+ # There is an obvious race condition here.
30
31
  id = @next_id.to_s
31
32
  @next_id+=1
32
33
 
33
- data['sandboxes'][id] = { :create_time => Time.now.utc, :checksums => sandbox_checksums }
34
+ time_str = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
35
+ time_str = "#{time_str[0..21]}:#{time_str[22..23]}"
36
+
37
+ create_data(request, request.rest_path, id, JSON.pretty_generate({
38
+ :create_time => time_str,
39
+ :checksums => sandbox_checksums
40
+ }))
34
41
 
35
42
  json_response(201, {
36
- :uri => build_uri(request.base_uri, request.rest_path + [id.to_s]),
43
+ :uri => build_uri(request.base_uri, request.rest_path + [id]),
37
44
  :checksums => result_checksums,
38
45
  :sandbox_id => id
39
46
  })
@@ -48,15 +48,15 @@ module ChefZero
48
48
  def search_container(request, index)
49
49
  case index
50
50
  when 'client'
51
- [ data['clients'], Proc.new { |client, name| DataNormalizer.normalize_client(client, name) }, build_uri(request.base_uri, [ 'clients' ]) ]
51
+ [ ['clients'], Proc.new { |client, name| DataNormalizer.normalize_client(client, name) }, build_uri(request.base_uri, [ 'clients' ]) ]
52
52
  when 'node'
53
- [ data['nodes'], Proc.new { |node, name| DataNormalizer.normalize_node(node, name) }, build_uri(request.base_uri, [ 'nodes' ]) ]
53
+ [ ['nodes'], Proc.new { |node, name| DataNormalizer.normalize_node(node, name) }, build_uri(request.base_uri, [ 'nodes' ]) ]
54
54
  when 'environment'
55
- [ data['environments'], Proc.new { |environment, name| DataNormalizer.normalize_environment(environment, name) }, build_uri(request.base_uri, [ 'environments' ]) ]
55
+ [ ['environments'], Proc.new { |environment, name| DataNormalizer.normalize_environment(environment, name) }, build_uri(request.base_uri, [ 'environments' ]) ]
56
56
  when 'role'
57
- [ data['roles'], Proc.new { |role, name| DataNormalizer.normalize_role(role, name) }, build_uri(request.base_uri, [ 'roles' ]) ]
57
+ [ ['roles'], Proc.new { |role, name| DataNormalizer.normalize_role(role, name) }, build_uri(request.base_uri, [ 'roles' ]) ]
58
58
  else
59
- [ data['data'][index], Proc.new { |data_bag_item, id| DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, 'DELETE') }, build_uri(request.base_uri, [ 'data', index ]) ]
59
+ [ ['data', index], Proc.new { |data_bag_item, id| DataNormalizer.normalize_data_bag_item(data_bag_item, index, id, 'DELETE') }, build_uri(request.base_uri, [ 'data', index ]) ]
60
60
  end
61
61
  end
62
62
 
@@ -101,13 +101,11 @@ module ChefZero
101
101
 
102
102
  # Get the search container
103
103
  container, expander, base_uri = search_container(request, index)
104
- if container.nil?
105
- raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
106
- end
107
104
 
108
105
  # Search!
109
106
  result = []
110
- container.each_pair do |name,value|
107
+ list_data(request, container).each do |name|
108
+ value = get_data(request, container + [name])
111
109
  expanded = expander.call(JSON.parse(value, :create_additions => false), name)
112
110
  result << [ name, build_uri(base_uri, [name]), expanded, expand_for_indexing(expanded, index, name) ]
113
111
  end
@@ -7,7 +7,7 @@ module ChefZero
7
7
  def get(request)
8
8
  # Get the result
9
9
  result_hash = {}
10
- indices = (%w(client environment node role) + data['data'].keys).sort
10
+ indices = (%w(client environment node role) + data_store.list(['data'])).sort
11
11
  indices.each do |index|
12
12
  result_hash[index] = build_uri(request.base_uri, request.rest_path + [index])
13
13
  end
@@ -1,5 +1,6 @@
1
1
  require 'chef_zero/rest_request'
2
2
  require 'chef_zero/rest_error_response'
3
+ require 'chef_zero/data_store/data_not_found_error'
3
4
 
4
5
  module ChefZero
5
6
  class RestBase
@@ -9,8 +10,8 @@ module ChefZero
9
10
 
10
11
  attr_reader :server
11
12
 
12
- def data
13
- server.data
13
+ def data_store
14
+ server.data_store
14
15
  end
15
16
 
16
17
  def call(request)
@@ -35,17 +36,74 @@ module ChefZero
35
36
  true
36
37
  end
37
38
 
38
- def get_data(request, rest_path=nil)
39
+ def get_data(request, rest_path=nil, *options)
39
40
  rest_path ||= request.rest_path
40
- # Grab the value we're looking for
41
- value = data
42
- rest_path.each do |path_part|
43
- if !value.has_key?(path_part)
41
+ begin
42
+ data_store.get(rest_path, request)
43
+ rescue DataStore::DataNotFoundError
44
+ if options.include?(:nil)
45
+ nil
46
+ else
44
47
  raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, rest_path)}")
45
48
  end
46
- value = value[path_part]
47
49
  end
48
- value
50
+ end
51
+
52
+ def list_data(request, rest_path=nil)
53
+ rest_path ||= request.rest_path
54
+ begin
55
+ data_store.list(rest_path)
56
+ rescue DataStore::DataNotFoundError
57
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, rest_path)}")
58
+ end
59
+ end
60
+
61
+ def delete_data(request, rest_path=nil)
62
+ rest_path ||= request.rest_path
63
+ begin
64
+ data_store.delete(rest_path)
65
+ rescue DataStore::DataNotFoundError
66
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
67
+ end
68
+ end
69
+
70
+ def delete_data_dir(request, rest_path, *options)
71
+ rest_path ||= request.rest_path
72
+ begin
73
+ data_store.delete_dir(rest_path)
74
+ rescue DataStore::DataNotFoundError
75
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
76
+ end
77
+ end
78
+
79
+ def set_data(request, rest_path, data, *options)
80
+ rest_path ||= request.rest_path
81
+ begin
82
+ data_store.set(rest_path, request.body, *options)
83
+ rescue DataStore::DataNotFoundError
84
+ raise RestErrorResponse.new(404, "Object not found: #{build_uri(request.base_uri, request.rest_path)}")
85
+ end
86
+ end
87
+
88
+ def create_data(request, rest_path, name, data, *options)
89
+ rest_path ||= request.rest_path
90
+ begin
91
+ data_store.create(rest_path, name, data, *options)
92
+ rescue DataStore::DataNotFoundError
93
+ raise RestErrorResponse.new(404, "Parent not found: #{build_uri(request.base_uri, request.rest_path)}")
94
+ rescue DataStore::DataAlreadyExistsError
95
+ raise RestErrorResponse.new(409, "Object already exists: #{build_uri(request.base_uri, request.rest_path + [name])}")
96
+ end
97
+ end
98
+
99
+ def exists_data?(request, rest_path=nil)
100
+ rest_path ||= request.rest_path
101
+ data_store.exists?(rest_path)
102
+ end
103
+
104
+ def exists_data_dir?(request, rest_path=nil)
105
+ rest_path ||= request.rest_path
106
+ data_store.exists_dir?(rest_path)
49
107
  end
50
108
 
51
109
  def error(response_code, error)
@@ -2,7 +2,11 @@ module ChefZero
2
2
  class RestRouter
3
3
  def initialize(routes)
4
4
  @routes = routes.map do |route, endpoint|
5
- pattern = Regexp.new("^#{route.gsub('*', '[^/]*')}$")
5
+ if route =~ /\*\*$/
6
+ pattern = Regexp.new("^#{route[0..-3].gsub('*', '[^/]*')}")
7
+ else
8
+ pattern = Regexp.new("^#{route.gsub('*', '[^/]*')}$")
9
+ end
6
10
  [ pattern, endpoint ]
7
11
  end
8
12
  end
@@ -24,6 +24,7 @@ require 'timeout'
24
24
  require 'chef_zero'
25
25
  require 'chef_zero/cookbook_data'
26
26
  require 'chef_zero/rest_router'
27
+ require 'chef_zero/data_store/memory_store'
27
28
  require 'chef_zero/version'
28
29
 
29
30
  require 'chef_zero/endpoints/authenticate_user_endpoint'
@@ -73,11 +74,11 @@ module ChefZero
73
74
  @server = Puma::Server.new(make_app, Puma::Events.new(STDERR, STDOUT))
74
75
  @server.add_tcp_listener(options[:host], options[:port])
75
76
 
76
- clear_data
77
+ @data_store = options[:data_store] || DataStore::MemoryStore.new
77
78
  end
78
79
 
79
80
  attr_reader :server
80
- attr_reader :data
81
+ attr_reader :data_store
81
82
  attr_reader :url
82
83
 
83
84
  include ChefZero::Endpoints
@@ -180,15 +181,18 @@ module ChefZero
180
181
  def load_data(contents)
181
182
  %w(clients environments nodes roles users).each do |data_type|
182
183
  if contents[data_type]
183
- data[data_type].merge!(dejsonize_children(contents[data_type]))
184
+ dejsonize_children(contents[data_type]).each_pair do |name, data|
185
+ data_store.create([data_type], name, data)
186
+ end
184
187
  end
185
188
  end
186
189
  if contents['data']
187
- new_data = {}
188
190
  contents['data'].each_pair do |key, data_bag|
189
- new_data[key] = dejsonize_children(data_bag)
191
+ data_store.create_dir(['data'], key, :keep_existing)
192
+ dejsonize_children(data_bag).each do |item_name, item|
193
+ data_store.set(['data', key], item_name, item, :create)
194
+ end
190
195
  end
191
- data['data'].merge!(new_data)
192
196
  end
193
197
  if contents['cookbooks']
194
198
  contents['cookbooks'].each_pair do |name_version, cookbook|
@@ -198,12 +202,12 @@ module ChefZero
198
202
  cookbook_data = CookbookData.to_hash(cookbook, name_version)
199
203
  end
200
204
  raise "No version specified" if !cookbook_data[:version]
201
- data['cookbooks'][cookbook_data[:cookbook_name]] = {} if !data['cookbooks'][cookbook_data[:cookbook_name]]
202
- data['cookbooks'][cookbook_data[:cookbook_name]][cookbook_data[:version]] = JSON.pretty_generate(cookbook_data)
205
+ data_store.create_dir(['cookbooks'], cookbook_data[:cookbook_name], :keep_existing)
206
+ data_store.set(['cookbooks', cookbook_data[:cookbook_name], cookbook_data[:version]], JSON.pretty_generate(cookbook_data), :create)
203
207
  cookbook_data.values.each do |files|
204
208
  next unless files.is_a? Array
205
209
  files.each do |file|
206
- data['file_store'][file[:checksum]] = get_file(cookbook, file[:path])
210
+ data_store.set(['file_store', 'checksums', file[:checksum]], get_file(cookbook, file[:path]), :create)
207
211
  end
208
212
  end
209
213
  end
@@ -211,24 +215,7 @@ module ChefZero
211
215
  end
212
216
 
213
217
  def clear_data
214
- @data = {
215
- 'clients' => {
216
- 'chef-validator' => '{ "validator": true }',
217
- 'chef-webui' => '{ "admin": true }'
218
- },
219
- 'cookbooks' => {},
220
- 'data' => {},
221
- 'environments' => {
222
- '_default' => '{ "description": "The default Chef environment" }'
223
- },
224
- 'file_store' => {},
225
- 'nodes' => {},
226
- 'roles' => {},
227
- 'sandboxes' => {},
228
- 'users' => {
229
- 'admin' => '{ "admin": true }'
230
- }
231
- }
218
+ @data_store.clear
232
219
  end
233
220
 
234
221
  def request_handler(&block)
@@ -270,7 +257,7 @@ module ChefZero
270
257
  [ '/users', ActorsEndpoint.new(self) ],
271
258
  [ '/users/*', ActorEndpoint.new(self) ],
272
259
 
273
- [ '/file_store/*', FileStoreFileEndpoint.new(self) ],
260
+ [ '/file_store/**', FileStoreFileEndpoint.new(self) ],
274
261
  ])
275
262
  router.not_found = NotFoundEndpoint.new
276
263
 
@@ -1,3 +1,3 @@
1
1
  module ChefZero
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: '1.1'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-20 00:00:00.000000000 Z
12
+ date: 2013-05-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: puma
@@ -106,6 +106,11 @@ files:
106
106
  - lib/chef_zero/core_ext/hash.rb
107
107
  - lib/chef_zero/core_ext.rb
108
108
  - lib/chef_zero/data_normalizer.rb
109
+ - lib/chef_zero/data_store/chef_fs_store.rb
110
+ - lib/chef_zero/data_store/data_already_exists_error.rb
111
+ - lib/chef_zero/data_store/data_error.rb
112
+ - lib/chef_zero/data_store/data_not_found_error.rb
113
+ - lib/chef_zero/data_store/memory_store.rb
109
114
  - lib/chef_zero/endpoints/actor_endpoint.rb
110
115
  - lib/chef_zero/endpoints/actors_endpoint.rb
111
116
  - lib/chef_zero/endpoints/authenticate_user_endpoint.rb