chef-zero 1.0.1 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/chef_zero/cookbook_data.rb +58 -24
- data/lib/chef_zero/data_normalizer.rb +1 -1
- data/lib/chef_zero/data_store/chef_fs_store.rb +96 -0
- data/lib/chef_zero/data_store/data_already_exists_error.rb +29 -0
- data/lib/chef_zero/data_store/data_error.rb +31 -0
- data/lib/chef_zero/data_store/data_not_found_error.rb +29 -0
- data/lib/chef_zero/data_store/memory_store.rb +164 -0
- data/lib/chef_zero/endpoints/authenticate_user_endpoint.rb +6 -2
- data/lib/chef_zero/endpoints/cookbook_endpoint.rb +4 -4
- data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +16 -12
- data/lib/chef_zero/endpoints/cookbooks_base.rb +10 -1
- data/lib/chef_zero/endpoints/cookbooks_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/data_bag_endpoint.rb +1 -6
- data/lib/chef_zero/endpoints/data_bags_endpoint.rb +2 -3
- data/lib/chef_zero/endpoints/environment_cookbook_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +13 -19
- data/lib/chef_zero/endpoints/environment_cookbooks_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/environment_nodes_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/environment_recipes_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/environment_role_endpoint.rb +1 -0
- data/lib/chef_zero/endpoints/file_store_file_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/principal_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/rest_list_endpoint.rb +2 -5
- data/lib/chef_zero/endpoints/rest_object_endpoint.rb +9 -13
- data/lib/chef_zero/endpoints/sandbox_endpoint.rb +4 -6
- data/lib/chef_zero/endpoints/sandboxes_endpoint.rb +11 -4
- data/lib/chef_zero/endpoints/search_endpoint.rb +7 -9
- data/lib/chef_zero/endpoints/searches_endpoint.rb +1 -1
- data/lib/chef_zero/rest_base.rb +67 -9
- data/lib/chef_zero/rest_router.rb +5 -1
- data/lib/chef_zero/server.rb +15 -28
- data/lib/chef_zero/version.rb +1 -1
- metadata +7 -2
@@ -18,6 +18,24 @@ module ChefZero
|
|
18
18
|
result
|
19
19
|
end
|
20
20
|
|
21
|
+
def self.metadata_from(directory, name, version, recipe_names)
|
22
|
+
metadata = PretendCookbookMetadata.new(PretendCookbook.new(name, recipe_names))
|
23
|
+
# If both .rb and .json exist, read .rb
|
24
|
+
# TODO if recipes has 3 recipes in it, and the Ruby/JSON has only one, should
|
25
|
+
# the resulting recipe list have 1, or 3-4 recipes in it?
|
26
|
+
if has_child(directory, 'metadata.rb')
|
27
|
+
metadata.instance_eval(read_file(directory, 'metadata.rb'))
|
28
|
+
elsif has_child(directory, 'metadata.json')
|
29
|
+
metadata.from_json(read_file(directory, 'metadata.json'))
|
30
|
+
end
|
31
|
+
result = {}
|
32
|
+
metadata.to_hash.each_pair do |key,value|
|
33
|
+
result[key.to_sym] = value
|
34
|
+
end
|
35
|
+
result[:version] = version if version
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
21
39
|
private
|
22
40
|
|
23
41
|
# Just enough cookbook to make a Metadata object
|
@@ -101,24 +119,6 @@ module ChefZero
|
|
101
119
|
end
|
102
120
|
end
|
103
121
|
|
104
|
-
def self.metadata_from(directory, name, version, recipe_names)
|
105
|
-
metadata = PretendCookbookMetadata.new(PretendCookbook.new(name, recipe_names))
|
106
|
-
# If both .rb and .json exist, read .rb
|
107
|
-
# TODO if recipes has 3 recipes in it, and the Ruby/JSON has only one, should
|
108
|
-
# the resulting recipe list have 1, or 3-4 recipes in it?
|
109
|
-
if directory['metadata.rb']
|
110
|
-
metadata.instance_eval(directory['metadata.rb'])
|
111
|
-
elsif directory['metadata.json']
|
112
|
-
metadata.from_json(directory['metadata.json'])
|
113
|
-
end
|
114
|
-
result = {}
|
115
|
-
metadata.to_hash.each_pair do |key,value|
|
116
|
-
result[key.to_sym] = value
|
117
|
-
end
|
118
|
-
result[:version] = version
|
119
|
-
result
|
120
|
-
end
|
121
|
-
|
122
122
|
def self.files_from(directory)
|
123
123
|
# TODO some support .rb only
|
124
124
|
result = {
|
@@ -137,8 +137,41 @@ module ChefZero
|
|
137
137
|
result
|
138
138
|
end
|
139
139
|
|
140
|
+
def self.has_child(directory, name)
|
141
|
+
if directory.is_a?(Hash)
|
142
|
+
directory.has_key?(name)
|
143
|
+
else
|
144
|
+
directory.child(name).exists?
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.read_file(directory, name)
|
149
|
+
if directory.is_a?(Hash)
|
150
|
+
directory[name]
|
151
|
+
else
|
152
|
+
directory.child(name).read
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.get_directory(directory, name)
|
157
|
+
if directory.is_a?(Hash)
|
158
|
+
directory[name].is_a?(Hash) ? directory[name] : nil
|
159
|
+
else
|
160
|
+
result = directory.child(name)
|
161
|
+
result.dir? ? result : nil
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.list_directory(directory)
|
166
|
+
if directory.is_a?(Hash)
|
167
|
+
directory.keys
|
168
|
+
else
|
169
|
+
directory.children.map { |c| c.name }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
140
173
|
def self.load_child_files(parent, key, recursive)
|
141
|
-
result = load_files(parent
|
174
|
+
result = load_files(get_directory(parent, key), recursive)
|
142
175
|
result.each do |file|
|
143
176
|
file[:path] = "#{key}/#{file[:path]}"
|
144
177
|
end
|
@@ -148,13 +181,14 @@ module ChefZero
|
|
148
181
|
def self.load_files(directory, recursive)
|
149
182
|
result = []
|
150
183
|
if directory
|
151
|
-
directory
|
152
|
-
|
184
|
+
list(directory) do |child_name|
|
185
|
+
dir = get_directory(directory, child_name)
|
186
|
+
if dir
|
153
187
|
if recursive
|
154
|
-
result += load_child_files(directory,
|
155
|
-
|
188
|
+
result += load_child_files(directory, child_name, recursive)
|
189
|
+
end
|
156
190
|
else
|
157
|
-
result += load_file(
|
191
|
+
result += load_file(read_file(directory, child_name), child_name)
|
158
192
|
end
|
159
193
|
end
|
160
194
|
end
|
@@ -64,7 +64,7 @@ module ChefZero
|
|
64
64
|
if value.is_a?(Array)
|
65
65
|
value.each do |file|
|
66
66
|
if file.is_a?(Hash) && file.has_key?('checksum')
|
67
|
-
file['url'] ||= RestBase::build_uri(base_uri, ['file_store', file['checksum']])
|
67
|
+
file['url'] ||= RestBase::build_uri(base_uri, ['file_store', 'checksums', file['checksum']])
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 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_fs/file_system'
|
20
|
+
require 'chef_fs/file_system/not_found_error'
|
21
|
+
require 'chef_zero/data_store/data_already_exists_error'
|
22
|
+
require 'chef_zero/data_store/data_not_found_error'
|
23
|
+
|
24
|
+
module ChefZero
|
25
|
+
module DataStore
|
26
|
+
class ChefFSStore
|
27
|
+
def initialize(chef_fs)
|
28
|
+
@chef_fs = chef_fs
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_dir(path, name, *options)
|
32
|
+
parent = get_dir(path, options.include?(:create_dir))
|
33
|
+
parent.create_child(name, nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create(path, name, data, *options)
|
37
|
+
if !data.is_a?(String)
|
38
|
+
raise "set only works with strings"
|
39
|
+
end
|
40
|
+
|
41
|
+
parent = get_dir(path, options.include?(:create_dir))
|
42
|
+
parent.create_child(name, data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def get(path)
|
46
|
+
begin
|
47
|
+
ChefFS::FileSystem.resolve_path(path.join('/')).read
|
48
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
49
|
+
raise DataNotFoundError.new(path, e)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def set(path, data, *options)
|
54
|
+
if !data.is_a?(String)
|
55
|
+
raise "set only works with strings: #{path} = #{data.inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
parent = get_dir(path[0..-2], options.include?(:create_dir))
|
59
|
+
parent.create_child(path[-1], data)
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete(path)
|
63
|
+
begin
|
64
|
+
ChefFS::FileSystem.resolve_path(path.join('/')).delete
|
65
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
66
|
+
raise DataNotFoundError.new(path, e)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def list(path)
|
71
|
+
begin
|
72
|
+
ChefFS::FileSystem.resolve_path(path.join('/')).children.map { |c| c.name }.sort
|
73
|
+
rescue ChefFS::FileSystem::NotFoundError => e
|
74
|
+
raise DataNotFoundError.new(path, e)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def exists?(path)
|
79
|
+
ChefFS::FileSystem.resolve_path(path.join('/')).exists?
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def get_dir(path, create=false)
|
85
|
+
result = Chef::FileSystem.resolve_path('/' + path.join('/'))
|
86
|
+
if result.exists?
|
87
|
+
result
|
88
|
+
elsif create
|
89
|
+
get_dir(path[0..-2], create).create_child(result.name, nil)
|
90
|
+
else
|
91
|
+
raise DataNotFoundError.new(path)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 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_zero/data_store/data_error'
|
20
|
+
|
21
|
+
module ChefZero
|
22
|
+
module DataStore
|
23
|
+
class DataAlreadyExistsError < DataError
|
24
|
+
def initialize(path, cause = nil)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 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
|
+
module ChefZero
|
20
|
+
module DataStore
|
21
|
+
class DataError < StandardError
|
22
|
+
def initialize(path, cause = nil)
|
23
|
+
@path = path
|
24
|
+
@cause = cause
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :path
|
28
|
+
attr_reader :cause
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 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_zero/data_store/data_error'
|
20
|
+
|
21
|
+
module ChefZero
|
22
|
+
module DataStore
|
23
|
+
class DataNotFoundError < DataError
|
24
|
+
def initialize(path, cause = nil)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#
|
2
|
+
# Author:: John Keiser (<jkeiser@opscode.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 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_zero/data_store/data_already_exists_error'
|
20
|
+
require 'chef_zero/data_store/data_not_found_error'
|
21
|
+
|
22
|
+
module ChefZero
|
23
|
+
module DataStore
|
24
|
+
class MemoryStore
|
25
|
+
def initialize
|
26
|
+
clear
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
@data = {}
|
31
|
+
|
32
|
+
# Create containers
|
33
|
+
create_dir([], 'clients')
|
34
|
+
create_dir([], 'cookbooks')
|
35
|
+
create_dir([], 'data')
|
36
|
+
create_dir([], 'environments')
|
37
|
+
create_dir([], 'file_store')
|
38
|
+
create_dir(['file_store'], 'checksums')
|
39
|
+
create_dir([], 'nodes')
|
40
|
+
create_dir([], 'roles')
|
41
|
+
create_dir([], 'sandboxes')
|
42
|
+
create_dir([], 'users')
|
43
|
+
|
44
|
+
# Set defaults
|
45
|
+
create(['clients'], 'chef-validator', '{ "validator": true }')
|
46
|
+
create(['clients'], 'chef-webui', '{ "admin": true }')
|
47
|
+
create(['environments'], '_default', '{ "description": "The default Chef environment" }')
|
48
|
+
create(['users'], 'admin', '{ "admin": true }')
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_dir(path, name, *options)
|
52
|
+
parent = _get(path, options.include?(:recursive))
|
53
|
+
|
54
|
+
if parent.has_key?(name)
|
55
|
+
raise DataAlreadyExistsError.new(path + [name])
|
56
|
+
end
|
57
|
+
parent[name] = {}
|
58
|
+
end
|
59
|
+
|
60
|
+
def create(path, name, data, *options)
|
61
|
+
if !data.is_a?(String)
|
62
|
+
raise "set only works with strings"
|
63
|
+
end
|
64
|
+
|
65
|
+
parent = _get(path, options.include?(:create_dir))
|
66
|
+
|
67
|
+
if parent.has_key?(name)
|
68
|
+
raise DataAlreadyExistsError.new(path + [name])
|
69
|
+
end
|
70
|
+
parent[name] = data
|
71
|
+
end
|
72
|
+
|
73
|
+
def get(path, request=nil)
|
74
|
+
value = _get(path)
|
75
|
+
if value.is_a?(Hash)
|
76
|
+
raise "get() called on directory #{path.join('/')}"
|
77
|
+
end
|
78
|
+
value
|
79
|
+
end
|
80
|
+
|
81
|
+
def set(path, data, *options)
|
82
|
+
if !data.is_a?(String)
|
83
|
+
raise "set only works with strings: #{path} = #{data.inspect}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get the parent
|
87
|
+
parent = _get(path[0..-2], options.include?(:create_dir))
|
88
|
+
|
89
|
+
if !options.include?(:create) && !parent[path[-1]]
|
90
|
+
raise DataNotFoundError.new(path)
|
91
|
+
end
|
92
|
+
parent[path[-1]] = data
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete(path)
|
96
|
+
parent = _get(path[0,path.length-1])
|
97
|
+
if !parent.has_key?(path[-1])
|
98
|
+
raise DataNotFoundError.new(path)
|
99
|
+
end
|
100
|
+
if !parent[path[-1]].is_a?(String)
|
101
|
+
raise "delete only works with strings: #{path}"
|
102
|
+
end
|
103
|
+
parent.delete(path[-1])
|
104
|
+
end
|
105
|
+
|
106
|
+
def delete_dir(path)
|
107
|
+
parent = _get(path[0,path.length-1])
|
108
|
+
if !parent.has_key?(path[-1])
|
109
|
+
raise DataNotFoundError.new(path)
|
110
|
+
end
|
111
|
+
if !parent[path[-1]].is_a?(Hash)
|
112
|
+
raise "delete_dir only works with directories: #{path}"
|
113
|
+
end
|
114
|
+
parent.delete(path[-1])
|
115
|
+
end
|
116
|
+
|
117
|
+
def list(path)
|
118
|
+
dir = _get(path)
|
119
|
+
if !dir.is_a? Hash
|
120
|
+
raise "list only works with directories (#{path} = #{dir.class}"
|
121
|
+
end
|
122
|
+
dir.keys.sort
|
123
|
+
end
|
124
|
+
|
125
|
+
def exists?(path)
|
126
|
+
begin
|
127
|
+
get(path)
|
128
|
+
return true
|
129
|
+
rescue DataNotFoundError
|
130
|
+
return false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def exists_dir?(path)
|
135
|
+
begin
|
136
|
+
dir = _get(path)
|
137
|
+
if !dir.is_a? Hash
|
138
|
+
raise "exists_dir? only works with directories (#{path} = #{dir.class}"
|
139
|
+
end
|
140
|
+
return true
|
141
|
+
rescue DataNotFoundError
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def _get(path, create_dir=false)
|
149
|
+
value = @data
|
150
|
+
path.each_with_index do |path_part, index|
|
151
|
+
if !value.has_key?(path_part)
|
152
|
+
if create_dir
|
153
|
+
value[path_part] = {}
|
154
|
+
else
|
155
|
+
raise DataNotFoundError.new(path[0,index+1])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
value = value[path_part]
|
159
|
+
end
|
160
|
+
value
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|