chef-zero 2.2.1 → 3.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/Rakefile +5 -1
  4. data/bin/chef-zero +17 -0
  5. data/lib/chef_zero/chef_data/acl_path.rb +139 -0
  6. data/lib/chef_zero/chef_data/cookbook_data.rb +240 -0
  7. data/lib/chef_zero/chef_data/data_normalizer.rb +207 -0
  8. data/lib/chef_zero/chef_data/default_creator.rb +446 -0
  9. data/lib/chef_zero/data_store/default_facade.rb +149 -0
  10. data/lib/chef_zero/data_store/interface_v1.rb +18 -0
  11. data/lib/chef_zero/data_store/memory_store.rb +2 -1
  12. data/lib/chef_zero/data_store/memory_store_v2.rb +3 -36
  13. data/lib/chef_zero/data_store/raw_file_store.rb +147 -0
  14. data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +39 -103
  15. data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +1 -1
  16. data/lib/chef_zero/endpoints/acl_endpoint.rb +38 -0
  17. data/lib/chef_zero/endpoints/acls_endpoint.rb +29 -0
  18. data/lib/chef_zero/endpoints/actor_endpoint.rb +36 -10
  19. data/lib/chef_zero/endpoints/actors_endpoint.rb +38 -6
  20. data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +15 -9
  21. data/lib/chef_zero/endpoints/container_endpoint.rb +22 -0
  22. data/lib/chef_zero/endpoints/containers_endpoint.rb +13 -0
  23. data/lib/chef_zero/endpoints/cookbook_endpoint.rb +1 -1
  24. data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +15 -14
  25. data/lib/chef_zero/endpoints/cookbooks_base.rb +2 -2
  26. data/lib/chef_zero/endpoints/data_bag_endpoint.rb +4 -4
  27. data/lib/chef_zero/endpoints/data_bag_item_endpoint.rb +5 -5
  28. data/lib/chef_zero/endpoints/data_bags_endpoint.rb +5 -4
  29. data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +2 -2
  30. data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +6 -6
  31. data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +2 -2
  32. data/lib/chef_zero/endpoints/environment_endpoint.rb +5 -5
  33. data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +2 -2
  34. data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +3 -3
  35. data/lib/chef_zero/endpoints/environment_role_endpoint.rb +2 -2
  36. data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +1 -1
  37. data/lib/chef_zero/endpoints/group_endpoint.rb +20 -0
  38. data/lib/chef_zero/endpoints/groups_endpoint.rb +13 -0
  39. data/lib/chef_zero/endpoints/license_endpoint.rb +25 -0
  40. data/lib/chef_zero/endpoints/node_endpoint.rb +5 -5
  41. data/lib/chef_zero/endpoints/not_found_endpoint.rb +2 -2
  42. data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +22 -0
  43. data/lib/chef_zero/endpoints/organization_association_requests_endpoint.rb +29 -0
  44. data/lib/chef_zero/endpoints/organization_authenticate_user_endpoint.rb +26 -0
  45. data/lib/chef_zero/endpoints/organization_endpoint.rb +41 -0
  46. data/lib/chef_zero/endpoints/organization_user_endpoint.rb +48 -0
  47. data/lib/chef_zero/endpoints/organization_users_endpoint.rb +14 -0
  48. data/lib/chef_zero/endpoints/organization_validator_key_endpoint.rb +20 -0
  49. data/lib/chef_zero/endpoints/organizations_endpoint.rb +55 -0
  50. data/lib/chef_zero/endpoints/principal_endpoint.rb +15 -3
  51. data/lib/chef_zero/endpoints/rest_list_endpoint.rb +8 -6
  52. data/lib/chef_zero/endpoints/rest_object_endpoint.rb +12 -10
  53. data/lib/chef_zero/endpoints/role_endpoint.rb +5 -5
  54. data/lib/chef_zero/endpoints/role_environments_endpoint.rb +2 -2
  55. data/lib/chef_zero/endpoints/sandbox_endpoint.rb +2 -2
  56. data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +4 -4
  57. data/lib/chef_zero/endpoints/search_endpoint.rb +10 -10
  58. data/lib/chef_zero/endpoints/system_recovery_endpoint.rb +30 -0
  59. data/lib/chef_zero/endpoints/user_association_request_endpoint.rb +40 -0
  60. data/lib/chef_zero/endpoints/user_association_requests_count_endpoint.rb +19 -0
  61. data/lib/chef_zero/endpoints/user_association_requests_endpoint.rb +19 -0
  62. data/lib/chef_zero/endpoints/user_organizations_endpoint.rb +22 -0
  63. data/lib/chef_zero/rest_base.rb +79 -13
  64. data/lib/chef_zero/rest_error_response.rb +1 -1
  65. data/lib/chef_zero/rest_request.rb +4 -0
  66. data/lib/chef_zero/rest_router.rb +1 -0
  67. data/lib/chef_zero/rspec.rb +55 -8
  68. data/lib/chef_zero/server.rb +87 -21
  69. data/lib/chef_zero/version.rb +1 -1
  70. data/spec/run_oc_pedant.rb +53 -0
  71. data/spec/{run.rb → run_pedant.rb} +13 -4
  72. data/spec/server_spec.rb +54 -0
  73. data/spec/support/oc_pedant.rb +134 -0
  74. data/spec/support/pedant.rb +1 -1
  75. metadata +54 -13
  76. data/lib/chef_zero/cookbook_data.rb +0 -236
  77. data/lib/chef_zero/data_normalizer.rb +0 -146
@@ -1,236 +0,0 @@
1
- require 'digest/md5'
2
- require 'hashie/mash'
3
-
4
- module ChefZero
5
- module CookbookData
6
- def self.to_hash(cookbook, name, version=nil)
7
- frozen = false
8
- if cookbook.has_key?(:frozen)
9
- frozen = cookbook[:frozen]
10
- cookbook = cookbook.dup
11
- cookbook.delete(:frozen)
12
- end
13
-
14
- result = files_from(cookbook)
15
- recipe_names = result[:recipes].map do |recipe|
16
- recipe_name = recipe[:name][0..-2]
17
- recipe_name == 'default' ? name : "#{name}::#{recipe_name}"
18
- end
19
- result[:metadata] = metadata_from(cookbook, name, version, recipe_names)
20
- result[:name] = "#{name}-#{result[:metadata][:version]}"
21
- result[:json_class] = 'Chef::CookbookVersion'
22
- result[:cookbook_name] = name
23
- result[:version] = result[:metadata][:version]
24
- result[:chef_type] = 'cookbook_version'
25
- result[:frozen?] = true if frozen
26
- result
27
- end
28
-
29
- def self.metadata_from(directory, name, version, recipe_names)
30
- metadata = PretendCookbookMetadata.new(PretendCookbook.new(name, recipe_names))
31
- # If both .rb and .json exist, read .rb
32
- # TODO if recipes has 3 recipes in it, and the Ruby/JSON has only one, should
33
- # the resulting recipe list have 1, or 3-4 recipes in it?
34
- if has_child(directory, 'metadata.rb')
35
- begin
36
- file = filename(directory, 'metadata.rb') || "(#{name}/metadata.rb)"
37
- metadata.instance_eval(read_file(directory, 'metadata.rb'), file)
38
- rescue
39
- ChefZero::Log.error("Error loading cookbook #{name}: #{$!}\n #{$!.backtrace.join("\n ")}")
40
- end
41
- elsif has_child(directory, 'metadata.json')
42
- metadata.from_json(read_file(directory, 'metadata.json'))
43
- end
44
- result = {}
45
- metadata.to_hash.each_pair do |key,value|
46
- result[key.to_sym] = value
47
- end
48
- result[:version] = version if version
49
- result
50
- end
51
-
52
- private
53
-
54
- # Just enough cookbook to make a Metadata object
55
- class PretendCookbook
56
- def initialize(name, fully_qualified_recipe_names)
57
- @name = name
58
- @fully_qualified_recipe_names = fully_qualified_recipe_names
59
- end
60
- attr_reader :name, :fully_qualified_recipe_names
61
- end
62
-
63
- # Handles loading configuration values from a Chef config file
64
- #
65
- # @author Justin Campbell <justin.campbell@riotgames.com>
66
- class PretendCookbookMetadata < Hash
67
- # @param [String] path
68
- def initialize(cookbook)
69
- self.name(cookbook.name)
70
- self.recipes(cookbook.fully_qualified_recipe_names)
71
- %w(attributes grouping dependencies supports recommendations suggestions conflicting providing replacing recipes).each do |hash_arg|
72
- self[hash_arg.to_sym] = Hashie::Mash.new
73
- end
74
- end
75
-
76
- def from_json(json)
77
- self.merge!(FFI_Yajl::Parser.parse(json))
78
- end
79
-
80
- private
81
-
82
- def depends(cookbook, *version_constraints)
83
- cookbook_arg(:dependencies, cookbook, version_constraints)
84
- end
85
-
86
- def supports(cookbook, *version_constraints)
87
- cookbook_arg(:supports, cookbook, version_constraints)
88
- end
89
-
90
- def recommends(cookbook, *version_constraints)
91
- cookbook_arg(:recommendations, cookbook, version_constraints)
92
- end
93
-
94
- def suggests(cookbook, *version_constraints)
95
- cookbook_arg(:suggestions, cookbook, version_constraints)
96
- end
97
-
98
- def conflicts(cookbook, *version_constraints)
99
- cookbook_arg(:conflicting, cookbook, version_constraints)
100
- end
101
-
102
- def provides(cookbook, *version_constraints)
103
- cookbook_arg(:providing, cookbook, version_constraints)
104
- end
105
-
106
- def replaces(cookbook, *version_constraints)
107
- cookbook_arg(:replacing, cookbook, version_constraints)
108
- end
109
-
110
- def recipe(recipe, description)
111
- self[:recipes][recipe] = description
112
- end
113
-
114
- def attribute(name, options)
115
- self[:attributes][name] = options
116
- end
117
-
118
- def grouping(name, options)
119
- self[:grouping][name] = options
120
- end
121
-
122
- def cookbook_arg(key, cookbook, version_constraints)
123
- self[key][cookbook] = version_constraints.first || ">= 0.0.0"
124
- end
125
-
126
- def method_missing(key, value = nil)
127
- if value.nil?
128
- self[key.to_sym]
129
- else
130
- store key.to_sym, value
131
- end
132
- end
133
- end
134
-
135
- def self.files_from(directory)
136
- # TODO some support .rb only
137
- result = {
138
- :attributes => load_child_files(directory, 'attributes', false),
139
- :definitions => load_child_files(directory, 'definitions', false),
140
- :recipes => load_child_files(directory, 'recipes', false),
141
- :libraries => load_child_files(directory, 'libraries', false),
142
- :templates => load_child_files(directory, 'templates', true),
143
- :files => load_child_files(directory, 'files', true),
144
- :resources => load_child_files(directory, 'resources', true),
145
- :providers => load_child_files(directory, 'providers', true),
146
- :root_files => load_files(directory, false)
147
- }
148
- set_specificity(result[:templates])
149
- set_specificity(result[:files])
150
- result
151
- end
152
-
153
- def self.has_child(directory, name)
154
- if directory.is_a?(Hash)
155
- directory.has_key?(name)
156
- else
157
- directory.child(name).exists?
158
- end
159
- end
160
-
161
- def self.read_file(directory, name)
162
- if directory.is_a?(Hash)
163
- directory[name]
164
- else
165
- directory.child(name).read
166
- end
167
- end
168
-
169
- def self.filename(directory, name)
170
- if directory.respond_to?(:file_path)
171
- File.join(directory.file_path, name)
172
- else
173
- nil
174
- end
175
- end
176
-
177
- def self.get_directory(directory, name)
178
- if directory.is_a?(Hash)
179
- directory[name].is_a?(Hash) ? directory[name] : nil
180
- else
181
- result = directory.child(name)
182
- result.dir? ? result : nil
183
- end
184
- end
185
-
186
- def self.list(directory)
187
- if directory.is_a?(Hash)
188
- directory.keys
189
- else
190
- directory.children.map { |c| c.name }
191
- end
192
- end
193
-
194
- def self.load_child_files(parent, key, recursive)
195
- result = load_files(get_directory(parent, key), recursive)
196
- result.each do |file|
197
- file[:path] = "#{key}/#{file[:path]}"
198
- end
199
- result
200
- end
201
-
202
- def self.load_files(directory, recursive)
203
- result = []
204
- if directory
205
- list(directory).each do |child_name|
206
- dir = get_directory(directory, child_name)
207
- if dir
208
- if recursive
209
- result += load_child_files(directory, child_name, recursive)
210
- end
211
- else
212
- result += load_file(read_file(directory, child_name), child_name)
213
- end
214
- end
215
- end
216
- result
217
- end
218
-
219
- def self.load_file(value, name)
220
- [{
221
- :name => name,
222
- :path => name,
223
- :checksum => Digest::MD5.hexdigest(value),
224
- :specificity => 'default'
225
- }]
226
- end
227
-
228
- def self.set_specificity(files)
229
- files.each do |file|
230
- parts = file[:path].split('/')
231
- raise "Only directories are allowed directly under templates or files: #{file[:path]}" if parts.size == 2
232
- file[:specificity] = parts[1]
233
- end
234
- end
235
- end
236
- end
@@ -1,146 +0,0 @@
1
- require 'chef_zero'
2
- require 'chef_zero/rest_base'
3
-
4
- module ChefZero
5
- class DataNormalizer
6
- def self.normalize_client(client, name)
7
- client['name'] ||= name
8
- client['admin'] ||= false
9
- client['admin'] = !!client['admin']
10
- client['public_key'] ||= PUBLIC_KEY
11
- client['validator'] ||= false
12
- client['validator'] = !!client['validator']
13
- client['json_class'] ||= "Chef::ApiClient"
14
- client['chef_type'] ||= "client"
15
- client
16
- end
17
-
18
- def self.normalize_user(user, name)
19
- user['name'] ||= name
20
- user['admin'] ||= false
21
- user['admin'] = !!user['admin']
22
- user['openid'] ||= nil
23
- user['public_key'] ||= PUBLIC_KEY
24
- user
25
- end
26
-
27
- def self.normalize_data_bag_item(data_bag_item, data_bag_name, id, method)
28
- if method == 'DELETE'
29
- # TODO SERIOUSLY, WHO DOES THIS MANY EXCEPTIONS IN THEIR INTERFACE
30
- if !(data_bag_item['json_class'] == 'Chef::DataBagItem' && data_bag_item['raw_data'])
31
- data_bag_item['id'] ||= id
32
- data_bag_item = { 'raw_data' => data_bag_item }
33
- data_bag_item['chef_type'] ||= 'data_bag_item'
34
- data_bag_item['json_class'] ||= 'Chef::DataBagItem'
35
- data_bag_item['data_bag'] ||= data_bag_name
36
- data_bag_item['name'] ||= "data_bag_item_#{data_bag_name}_#{id}"
37
- end
38
- else
39
- # If it's not already wrapped with raw_data, wrap it.
40
- if data_bag_item['json_class'] == 'Chef::DataBagItem' && data_bag_item['raw_data']
41
- data_bag_item = data_bag_item['raw_data']
42
- end
43
- # Argh. We don't do this on GET, but we do on PUT and POST????
44
- if %w(PUT POST).include?(method)
45
- data_bag_item['chef_type'] ||= 'data_bag_item'
46
- data_bag_item['data_bag'] ||= data_bag_name
47
- end
48
- data_bag_item['id'] ||= id
49
- end
50
- data_bag_item
51
- end
52
-
53
- def self.normalize_environment(environment, name)
54
- environment['name'] ||= name
55
- environment['description'] ||= ''
56
- environment['cookbook_versions'] ||= {}
57
- environment['json_class'] ||= "Chef::Environment"
58
- environment['chef_type'] ||= "environment"
59
- environment['default_attributes'] ||= {}
60
- environment['override_attributes'] ||= {}
61
- environment
62
- end
63
-
64
- def self.normalize_cookbook(endpoint, org_prefix, cookbook, name, version, base_uri, method)
65
- # TODO I feel dirty
66
- if method != 'PUT'
67
- cookbook.each_pair do |key, value|
68
- if value.is_a?(Array)
69
- value.each do |file|
70
- if file.is_a?(Hash) && file.has_key?('checksum')
71
- file['url'] ||= endpoint.build_uri(base_uri, org_prefix + ['file_store', 'checksums', file['checksum']])
72
- end
73
- end
74
- end
75
- end
76
- cookbook['name'] ||= "#{name}-#{version}"
77
- # TODO this feels wrong, but the real chef server doesn't expand this default
78
- # cookbook['version'] ||= version
79
- cookbook['cookbook_name'] ||= name
80
- cookbook['frozen?'] ||= false
81
- cookbook['metadata'] ||= {}
82
- cookbook['metadata']['version'] ||= version
83
- # Sad to not be expanding defaults just because Chef doesn't :(
84
- # cookbook['metadata']['name'] ||= name
85
- # cookbook['metadata']['description'] ||= "A fabulous new cookbook"
86
- cookbook['metadata']['long_description'] ||= ""
87
- # cookbook['metadata']['maintainer'] ||= "YOUR_COMPANY_NAME"
88
- # cookbook['metadata']['maintainer_email'] ||= "YOUR_EMAIL"
89
- # cookbook['metadata']['license'] ||= "none"
90
- cookbook['metadata']['dependencies'] ||= {}
91
- cookbook['metadata']['attributes'] ||= {}
92
- cookbook['metadata']['recipes'] ||= {}
93
- end
94
- cookbook['json_class'] ||= 'Chef::CookbookVersion'
95
- cookbook['chef_type'] ||= 'cookbook_version'
96
- if method == 'MIN'
97
- cookbook['metadata'].delete('attributes')
98
- cookbook['metadata'].delete('long_description')
99
- end
100
- cookbook
101
- end
102
-
103
- def self.normalize_node(node, name)
104
- node['name'] ||= name
105
- node['json_class'] ||= 'Chef::Node'
106
- node['chef_type'] ||= 'node'
107
- node['chef_environment'] ||= '_default'
108
- node['override'] ||= {}
109
- node['normal'] ||= {}
110
- node['default'] ||= {}
111
- node['automatic'] ||= {}
112
- node['run_list'] ||= []
113
- node['run_list'] = normalize_run_list(node['run_list'])
114
- node
115
- end
116
-
117
- def self.normalize_role(role, name)
118
- role['name'] ||= name
119
- role['description'] ||= ''
120
- role['json_class'] ||= 'Chef::Role'
121
- role['chef_type'] ||= 'role'
122
- role['default_attributes'] ||= {}
123
- role['override_attributes'] ||= {}
124
- role['run_list'] ||= []
125
- role['run_list'] = normalize_run_list(role['run_list'])
126
- role['env_run_lists'] ||= {}
127
- role['env_run_lists'].each_pair do |env, run_list|
128
- role['env_run_lists'][env] = normalize_run_list(run_list)
129
- end
130
- role
131
- end
132
-
133
- def self.normalize_run_list(run_list)
134
- run_list.map{|item|
135
- case item
136
- when /^recipe\[.*\]$/
137
- item # explicit recipe
138
- when /^role\[.*\]$/
139
- item # explicit role
140
- else
141
- "recipe[#{item}]"
142
- end
143
- }.uniq
144
- end
145
- end
146
- end