chef-zero 13.1.0 → 14.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.
- checksums.yaml +5 -5
- data/Gemfile +2 -6
- data/Rakefile +0 -13
- data/chef-zero.gemspec +2 -2
- data/lib/chef_zero/chef_data/acl_path.rb +2 -2
- data/lib/chef_zero/chef_data/cookbook_data.rb +150 -148
- data/lib/chef_zero/chef_data/default_creator.rb +5 -5
- data/lib/chef_zero/data_store/default_facade.rb +7 -9
- data/lib/chef_zero/data_store/memory_store_v2.rb +12 -16
- data/lib/chef_zero/data_store/raw_file_store.rb +11 -17
- data/lib/chef_zero/data_store/v1_to_v2_adapter.rb +9 -11
- data/lib/chef_zero/data_store/v2_to_v1_adapter.rb +5 -7
- data/lib/chef_zero/endpoints/actor_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/actors_endpoint.rb +3 -3
- data/lib/chef_zero/endpoints/cookbook_artifact_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/cookbook_artifact_identifier_endpoint.rb +21 -23
- data/lib/chef_zero/endpoints/cookbook_artifacts_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/cookbook_version_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/cookbooks_base.rb +1 -1
- data/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/not_found_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/organization_association_request_endpoint.rb +0 -1
- data/lib/chef_zero/endpoints/policies_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/policy_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/policy_group_policy_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/policy_revision_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/policy_revisions_endpoint.rb +1 -1
- data/lib/chef_zero/endpoints/rest_object_endpoint.rb +2 -2
- data/lib/chef_zero/endpoints/search_endpoint.rb +3 -5
- data/lib/chef_zero/rest_base.rb +4 -4
- data/lib/chef_zero/rest_request.rb +1 -1
- data/lib/chef_zero/rspec.rb +4 -2
- data/lib/chef_zero/server.rb +1 -1
- data/lib/chef_zero/socketless_server_map.rb +1 -1
- data/lib/chef_zero/solr/query/term.rb +1 -1
- data/lib/chef_zero/solr/solr_parser.rb +1 -1
- data/lib/chef_zero/version.rb +1 -1
- data/spec/run_oc_pedant.rb +2 -2
- data/spec/search_spec.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: de5e799dbc573fb80aba7bdc43fbbbe2590a6069bec55699176ae6c018438e1c
|
4
|
+
data.tar.gz: de13a5194e116d360c202afa163b119e7c668ed97dc4e456cb0bdbbc317fc2de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76de13ce02f1972a2e920568cb0e26d704d1fb4882ce4ee28b48f3284815b66d8fcee96cd584112b57ad8be26935af0d8d428594db23bd38affc8566c63d34d3
|
7
|
+
data.tar.gz: e6628d9d3ab273f70bb327d725fe7e5b705d62347f6d0b2761c90f9b93ed267691869704887c7a71122823006c2631c482456649ddbbf5743c044fe430694391
|
data/Gemfile
CHANGED
@@ -7,15 +7,11 @@ group :pedant do
|
|
7
7
|
gem "oc-chef-pedant", :git => "https://github.com/chef/chef-server.git"
|
8
8
|
end
|
9
9
|
|
10
|
-
group :changelog do
|
11
|
-
gem "github_changelog_generator", :git => "https://github.com/chef/github-changelog-generator.git"
|
12
|
-
end
|
13
|
-
|
14
10
|
group :development, :test do
|
15
|
-
gem "chefstyle", "
|
11
|
+
gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "master"
|
16
12
|
end
|
17
13
|
|
18
|
-
gem "chef", "
|
14
|
+
gem "chef", git: "https://github.com/chef/chef.git", branch: "tm/inject_log"
|
19
15
|
|
20
16
|
if ENV["GEMFILE_MOD"]
|
21
17
|
puts "GEMFILE_MOD: #{ENV['GEMFILE_MOD']}"
|
data/Rakefile
CHANGED
@@ -61,16 +61,3 @@ begin
|
|
61
61
|
rescue LoadError
|
62
62
|
puts "chefstyle/rubocop is not available. gem install chefstyle to do style checking."
|
63
63
|
end
|
64
|
-
|
65
|
-
begin
|
66
|
-
require "github_changelog_generator/task"
|
67
|
-
|
68
|
-
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
69
|
-
config.future_release = ChefZero::VERSION
|
70
|
-
config.issues = false
|
71
|
-
config.enhancement_labels = "enhancement,Enhancement,New Feature,Feature".split(",")
|
72
|
-
config.bug_labels = "bug,Bug,Improvement,Upstream Bug".split(",")
|
73
|
-
end
|
74
|
-
rescue LoadError
|
75
|
-
puts "github_changelog_generator is not available. gem install github_changelog_generator to generate changelogs"
|
76
|
-
end
|
data/chef-zero.gemspec
CHANGED
@@ -12,9 +12,9 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.homepage = "http://www.chef.io"
|
13
13
|
s.license = "Apache 2.0"
|
14
14
|
|
15
|
-
s.required_ruby_version = ">= 2.3
|
15
|
+
s.required_ruby_version = ">= 2.4.3"
|
16
16
|
|
17
|
-
s.add_dependency "mixlib-log", "~>
|
17
|
+
s.add_dependency "mixlib-log", "~> 2"
|
18
18
|
s.add_dependency "hashie", ">= 2.0", "< 4.0"
|
19
19
|
s.add_dependency "uuidtools", "~> 2.1"
|
20
20
|
s.add_dependency "ffi-yajl", "~> 2.2"
|
@@ -104,14 +104,13 @@ module ChefZero
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
private
|
108
|
-
|
109
107
|
# /acls/root -> nil
|
110
108
|
# /acls/containers/containers -> /acls/root
|
111
109
|
# /acls/TYPE/X -> /acls/containers/TYPE
|
112
110
|
#
|
113
111
|
# Method *assumes* acl_data_path is valid.
|
114
112
|
# Returns nil if the path is /acls/root
|
113
|
+
private_class_method
|
115
114
|
def self.partition_parent_acl_data_path(acl_data_path)
|
116
115
|
if acl_data_path.size == 3
|
117
116
|
if acl_data_path == %w{acls containers containers}
|
@@ -124,6 +123,7 @@ module ChefZero
|
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
126
|
+
private_class_method
|
127
127
|
def self.partition_acl_data_path(path, data_types)
|
128
128
|
if path.size == 0
|
129
129
|
%w{acls root}
|
@@ -4,53 +4,158 @@ require "hashie"
|
|
4
4
|
module ChefZero
|
5
5
|
module ChefData
|
6
6
|
module CookbookData
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
7
|
+
class << self
|
8
|
+
def to_hash(cookbook, name, version = nil)
|
9
|
+
frozen = false
|
10
|
+
if cookbook.has_key?(:frozen)
|
11
|
+
frozen = cookbook[:frozen]
|
12
|
+
cookbook = cookbook.dup
|
13
|
+
cookbook.delete(:frozen)
|
14
|
+
end
|
15
|
+
|
16
|
+
result = files_from(cookbook)
|
17
|
+
recipe_names = result[:all_files].select do |file|
|
18
|
+
file[:name].start_with?("recipes/")
|
19
|
+
end.map do |recipe|
|
20
|
+
recipe_name = recipe[:name][0..-2]
|
21
|
+
recipe_name == "default" ? name : "#{name}::#{recipe_name}"
|
22
|
+
end
|
23
|
+
result[:metadata] = metadata_from(cookbook, name, version, recipe_names)
|
24
|
+
result[:name] = "#{name}-#{result[:metadata][:version]}"
|
25
|
+
result[:json_class] = "Chef::CookbookVersion"
|
26
|
+
result[:cookbook_name] = name
|
27
|
+
result[:version] = result[:metadata][:version]
|
28
|
+
result[:chef_type] = "cookbook_version"
|
29
|
+
result[:frozen?] = true if frozen
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
def metadata_from(directory, name, version, recipe_names)
|
34
|
+
metadata = PretendCookbookMetadata.new(PretendCookbook.new(name, recipe_names))
|
35
|
+
# If both .rb and .json exist, read .json
|
36
|
+
if has_child(directory, "metadata.json")
|
37
|
+
metadata.from_json(read_file(directory, "metadata.json"))
|
38
|
+
elsif has_child(directory, "metadata.rb")
|
39
|
+
begin
|
40
|
+
file = filename(directory, "metadata.rb") || "(#{name}/metadata.rb)"
|
41
|
+
metadata.instance_eval(read_file(directory, "metadata.rb"), file)
|
42
|
+
rescue
|
43
|
+
ChefZero::Log.error("Error loading cookbook #{name}: #{$!}\n #{$!.backtrace.join("\n ")}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
result = {}
|
47
|
+
metadata.to_hash.each_pair do |key, value|
|
48
|
+
result[key.to_sym] = value
|
49
|
+
end
|
50
|
+
result[:version] = version if version
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
31
55
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
56
|
+
def files_from(directory)
|
57
|
+
# TODO some support .rb only
|
58
|
+
result = load_files(directory)
|
59
|
+
|
60
|
+
set_specificity(result, :templates)
|
61
|
+
set_specificity(result, :files)
|
62
|
+
|
63
|
+
result = {
|
64
|
+
all_files: result,
|
65
|
+
}
|
66
|
+
result
|
67
|
+
end
|
68
|
+
|
69
|
+
def has_child(directory, name)
|
70
|
+
if directory.is_a?(Hash)
|
71
|
+
directory.has_key?(name)
|
72
|
+
else
|
73
|
+
directory.child(name).exists?
|
43
74
|
end
|
44
75
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
76
|
+
|
77
|
+
def read_file(directory, name)
|
78
|
+
if directory.is_a?(Hash)
|
79
|
+
directory[name]
|
80
|
+
else
|
81
|
+
directory.child(name).read
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def filename(directory, name)
|
86
|
+
if directory.respond_to?(:file_path)
|
87
|
+
File.join(directory.file_path, name)
|
88
|
+
else
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_directory(directory, name)
|
94
|
+
if directory.is_a?(Hash)
|
95
|
+
directory[name].is_a?(Hash) ? directory[name] : nil
|
96
|
+
else
|
97
|
+
result = directory.child(name)
|
98
|
+
result.dir? ? result : nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def list(directory)
|
103
|
+
if directory.is_a?(Hash)
|
104
|
+
directory.keys
|
105
|
+
else
|
106
|
+
directory.children.map { |c| c.name }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def load_child_files(parent, key, recursive, part)
|
111
|
+
result = load_files(get_directory(parent, key), recursive, part)
|
112
|
+
result.each do |file|
|
113
|
+
file[:path] = "#{key}/#{file[:path]}"
|
114
|
+
end
|
115
|
+
result
|
116
|
+
end
|
117
|
+
|
118
|
+
def load_files(directory, recursive = true, part = nil)
|
119
|
+
result = []
|
120
|
+
if directory
|
121
|
+
list(directory).each do |child_name|
|
122
|
+
dir = get_directory(directory, child_name)
|
123
|
+
if dir
|
124
|
+
child_part = child_name if part.nil?
|
125
|
+
if recursive
|
126
|
+
result += load_child_files(directory, child_name, recursive, child_part)
|
127
|
+
end
|
128
|
+
else
|
129
|
+
result += load_file(read_file(directory, child_name), child_name, part)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
result
|
134
|
+
end
|
135
|
+
|
136
|
+
def load_file(value, name, part = nil)
|
137
|
+
specific_name = part ? "#{part}/#{name}" : name
|
138
|
+
[{
|
139
|
+
:name => specific_name,
|
140
|
+
:path => name,
|
141
|
+
:checksum => Digest::MD5.hexdigest(value),
|
142
|
+
:specificity => "default",
|
143
|
+
}]
|
48
144
|
end
|
49
|
-
result[:version] = version if version
|
50
|
-
result
|
51
|
-
end
|
52
145
|
|
53
|
-
|
146
|
+
def set_specificity(files, type)
|
147
|
+
files.each do |file|
|
148
|
+
next unless file[:name].split("/")[0] == type.to_s
|
149
|
+
|
150
|
+
parts = file[:path].split("/")
|
151
|
+
file[:specificity] = if parts.size == 2
|
152
|
+
"default"
|
153
|
+
else
|
154
|
+
parts[1]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
54
159
|
|
55
160
|
# Just enough cookbook to make a Metadata object
|
56
161
|
class PretendCookbook
|
@@ -67,15 +172,15 @@ module ChefZero
|
|
67
172
|
class PretendCookbookMetadata < Hash
|
68
173
|
# @param [String] path
|
69
174
|
def initialize(cookbook)
|
70
|
-
|
71
|
-
|
175
|
+
name(cookbook.name)
|
176
|
+
recipes(cookbook.fully_qualified_recipe_names)
|
72
177
|
%w{attributes grouping dependencies supports recommendations suggestions conflicting providing replacing recipes}.each do |hash_arg|
|
73
178
|
self[hash_arg.to_sym] = Hashie::Mash.new
|
74
179
|
end
|
75
180
|
end
|
76
181
|
|
77
182
|
def from_json(json)
|
78
|
-
|
183
|
+
merge!(FFI_Yajl::Parser.parse(json))
|
79
184
|
end
|
80
185
|
|
81
186
|
private
|
@@ -121,109 +226,6 @@ module ChefZero
|
|
121
226
|
end
|
122
227
|
end
|
123
228
|
end
|
124
|
-
|
125
|
-
def self.files_from(directory)
|
126
|
-
# TODO some support .rb only
|
127
|
-
result = load_files(directory)
|
128
|
-
|
129
|
-
set_specificity(result, :templates)
|
130
|
-
set_specificity(result, :files)
|
131
|
-
|
132
|
-
result = {
|
133
|
-
all_files: result,
|
134
|
-
}
|
135
|
-
result
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.has_child(directory, name)
|
139
|
-
if directory.is_a?(Hash)
|
140
|
-
directory.has_key?(name)
|
141
|
-
else
|
142
|
-
directory.child(name).exists?
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def self.read_file(directory, name)
|
147
|
-
if directory.is_a?(Hash)
|
148
|
-
directory[name]
|
149
|
-
else
|
150
|
-
directory.child(name).read
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def self.filename(directory, name)
|
155
|
-
if directory.respond_to?(:file_path)
|
156
|
-
File.join(directory.file_path, name)
|
157
|
-
else
|
158
|
-
nil
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def self.get_directory(directory, name)
|
163
|
-
if directory.is_a?(Hash)
|
164
|
-
directory[name].is_a?(Hash) ? directory[name] : nil
|
165
|
-
else
|
166
|
-
result = directory.child(name)
|
167
|
-
result.dir? ? result : nil
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def self.list(directory)
|
172
|
-
if directory.is_a?(Hash)
|
173
|
-
directory.keys
|
174
|
-
else
|
175
|
-
directory.children.map { |c| c.name }
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.load_child_files(parent, key, recursive, part)
|
180
|
-
result = load_files(get_directory(parent, key), recursive, part)
|
181
|
-
result.each do |file|
|
182
|
-
file[:path] = "#{key}/#{file[:path]}"
|
183
|
-
end
|
184
|
-
result
|
185
|
-
end
|
186
|
-
|
187
|
-
def self.load_files(directory, recursive = true, part = nil)
|
188
|
-
result = []
|
189
|
-
if directory
|
190
|
-
list(directory).each do |child_name|
|
191
|
-
dir = get_directory(directory, child_name)
|
192
|
-
if dir
|
193
|
-
child_part = child_name if part.nil?
|
194
|
-
if recursive
|
195
|
-
result += load_child_files(directory, child_name, recursive, child_part)
|
196
|
-
end
|
197
|
-
else
|
198
|
-
result += load_file(read_file(directory, child_name), child_name, part)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
result
|
203
|
-
end
|
204
|
-
|
205
|
-
def self.load_file(value, name, part = nil)
|
206
|
-
specific_name = part ? "#{part}/#{name}" : name
|
207
|
-
[{
|
208
|
-
:name => specific_name,
|
209
|
-
:path => name,
|
210
|
-
:checksum => Digest::MD5.hexdigest(value),
|
211
|
-
:specificity => "default",
|
212
|
-
}]
|
213
|
-
end
|
214
|
-
|
215
|
-
def self.set_specificity(files, type)
|
216
|
-
files.each do |file|
|
217
|
-
next unless file[:name].split("/")[0] == type.to_s
|
218
|
-
|
219
|
-
parts = file[:path].split("/")
|
220
|
-
file[:specificity] = if parts.size == 2
|
221
|
-
"default"
|
222
|
-
else
|
223
|
-
parts[1]
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
229
|
end
|
228
230
|
end
|
229
231
|
|
@@ -455,17 +455,17 @@ module ChefZero
|
|
455
455
|
when 0, 1
|
456
456
|
return true
|
457
457
|
when 2
|
458
|
-
|
458
|
+
path[0] == "organizations" || (path[0] == "acls" && path[1] != "root")
|
459
459
|
when 3
|
460
460
|
# If it has a container, it is a directory.
|
461
|
-
|
462
|
-
|
461
|
+
path[0] == "organizations" &&
|
462
|
+
(path[2] == "acls" || data.exists?(path[0..1] + [ "containers", path[2] ]))
|
463
463
|
when 4
|
464
|
-
|
464
|
+
path[0] == "organizations" && (
|
465
465
|
(path[2] == "acls" && path[1] != "root") ||
|
466
466
|
%w{cookbooks cookbook_artifacts data policies policy_groups}.include?(path[2]))
|
467
467
|
else
|
468
|
-
|
468
|
+
false
|
469
469
|
end
|
470
470
|
end
|
471
471
|
end
|
@@ -66,15 +66,13 @@ module ChefZero
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def get(path, request = nil)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
raise
|
77
|
-
end
|
69
|
+
real_store.get(path, request)
|
70
|
+
rescue DataNotFoundError
|
71
|
+
result = default_creator.get(path)
|
72
|
+
if result
|
73
|
+
FFI_Yajl::Encoder.encode(result, :pretty => true)
|
74
|
+
else
|
75
|
+
raise
|
78
76
|
end
|
79
77
|
end
|
80
78
|
|
@@ -111,27 +111,23 @@ module ChefZero
|
|
111
111
|
end
|
112
112
|
|
113
113
|
def exists?(path, options = {})
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
raise "exists? does not work with directories (#{path} = #{value.class})"
|
118
|
-
end
|
119
|
-
return true
|
120
|
-
rescue DataNotFoundError
|
121
|
-
return false
|
114
|
+
value = _get(path)
|
115
|
+
if value.is_a?(Hash) && !options[:allow_dirs]
|
116
|
+
raise "exists? does not work with directories (#{path} = #{value.class})"
|
122
117
|
end
|
118
|
+
return true
|
119
|
+
rescue DataNotFoundError
|
120
|
+
return false
|
123
121
|
end
|
124
122
|
|
125
123
|
def exists_dir?(path)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
raise "exists_dir? only works with directories (#{path} = #{dir.class})"
|
130
|
-
end
|
131
|
-
return true
|
132
|
-
rescue DataNotFoundError
|
133
|
-
return false
|
124
|
+
dir = _get(path)
|
125
|
+
if !dir.is_a? Hash
|
126
|
+
raise "exists_dir? only works with directories (#{path} = #{dir.class})"
|
134
127
|
end
|
128
|
+
return true
|
129
|
+
rescue DataNotFoundError
|
130
|
+
return false
|
135
131
|
end
|
136
132
|
|
137
133
|
private
|
@@ -80,11 +80,9 @@ module ChefZero
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def get(path, request = nil)
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
raise DataNotFoundError.new(path)
|
87
|
-
end
|
83
|
+
return IO.read(path_to(path))
|
84
|
+
rescue Errno::ENOENT
|
85
|
+
raise DataNotFoundError.new(path)
|
88
86
|
end
|
89
87
|
|
90
88
|
def set(path, data, *options)
|
@@ -105,11 +103,9 @@ module ChefZero
|
|
105
103
|
end
|
106
104
|
|
107
105
|
def delete(path)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
raise DataNotFoundError.new(path)
|
112
|
-
end
|
106
|
+
File.delete(path_to(path))
|
107
|
+
rescue Errno::ENOENT
|
108
|
+
raise DataNotFoundError.new(path)
|
113
109
|
end
|
114
110
|
|
115
111
|
def delete_dir(path, *options)
|
@@ -128,19 +124,17 @@ module ChefZero
|
|
128
124
|
end
|
129
125
|
|
130
126
|
def list(path)
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
raise DataNotFoundError.new(path)
|
135
|
-
end
|
127
|
+
Dir.entries(path_to(path)).select { |entry| entry != "." && entry != ".." }.to_a
|
128
|
+
rescue Errno::ENOENT
|
129
|
+
raise DataNotFoundError.new(path)
|
136
130
|
end
|
137
131
|
|
138
132
|
def exists?(path, options = {})
|
139
|
-
File.
|
133
|
+
File.exist?(path_to(path))
|
140
134
|
end
|
141
135
|
|
142
136
|
def exists_dir?(path)
|
143
|
-
File.
|
137
|
+
File.exist?(path_to(path))
|
144
138
|
end
|
145
139
|
end
|
146
140
|
end
|
@@ -109,17 +109,15 @@ module ChefZero
|
|
109
109
|
private
|
110
110
|
|
111
111
|
def fix_exceptions
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
raise e
|
122
|
-
end
|
112
|
+
yield
|
113
|
+
rescue DataAlreadyExistsError => e
|
114
|
+
err = DataAlreadyExistsError.new([ "organizations", single_org ] + e.path, e)
|
115
|
+
err.set_backtrace(e.backtrace)
|
116
|
+
raise err
|
117
|
+
rescue DataNotFoundError => e
|
118
|
+
err = DataNotFoundError.new([ "organizations", single_org ] + e.path, e)
|
119
|
+
err.set_backtrace(e.backtrace)
|
120
|
+
raise e
|
123
121
|
end
|
124
122
|
|
125
123
|
def skip_organizations?(path, name = nil)
|
@@ -90,13 +90,11 @@ module ChefZero
|
|
90
90
|
protected
|
91
91
|
|
92
92
|
def fix_exceptions
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
raise DataNotFoundError.new(e.path[2..-1], e)
|
99
|
-
end
|
93
|
+
yield
|
94
|
+
rescue DataAlreadyExistsError => e
|
95
|
+
raise DataAlreadyExistsError.new(e.path[2..-1], e)
|
96
|
+
rescue DataNotFoundError => e
|
97
|
+
raise DataNotFoundError.new(e.path[2..-1], e)
|
100
98
|
end
|
101
99
|
|
102
100
|
def fix_path(path)
|
@@ -156,7 +156,7 @@ module ChefZero
|
|
156
156
|
|
157
157
|
def client?(request, rest_path = nil)
|
158
158
|
rest_path ||= request.rest_path
|
159
|
-
|
159
|
+
rest_path[2] == "clients"
|
160
160
|
end
|
161
161
|
|
162
162
|
# Return the data store keys path for the request client or user, e.g.
|
@@ -10,9 +10,9 @@ module ChefZero
|
|
10
10
|
|
11
11
|
# apply query filters: if one applies, stop processing rest
|
12
12
|
# (precendence matches chef-server: https://github.com/chef/chef-server/blob/268a0c9/src/oc_erchef/apps/chef_objects/src/chef_user.erl#L554-L559)
|
13
|
-
if value = request.query_params["external_authentication_uid"]
|
13
|
+
if (value = request.query_params["external_authentication_uid"])
|
14
14
|
response[2] = filter("external_authentication_uid", value, request, response[2])
|
15
|
-
elsif value = request.query_params["email"]
|
15
|
+
elsif (value = request.query_params["email"])
|
16
16
|
response[2] = filter("email", value, request, response[2], insensitive: true)
|
17
17
|
end
|
18
18
|
|
@@ -97,7 +97,7 @@ module ChefZero
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def is_equal(a, b, ignore_case)
|
100
|
-
ignore_case ? a.casecmp(b)
|
100
|
+
ignore_case ? a.casecmp(b) == 0 : a == b
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -10,7 +10,7 @@ module ChefZero
|
|
10
10
|
# GET /organizations/ORG/cookbook_artifacts/NAME/IDENTIFIER
|
11
11
|
def get(request)
|
12
12
|
cookbook_data = normalize(request, get_data(request))
|
13
|
-
|
13
|
+
json_response(200, cookbook_data)
|
14
14
|
end
|
15
15
|
|
16
16
|
# PUT /organizations/ORG/cookbook_artifacts/COOKBOOK/IDENTIFIER
|
@@ -20,36 +20,34 @@ module ChefZero
|
|
20
20
|
end
|
21
21
|
|
22
22
|
cb_data = normalize(request, request.body)
|
23
|
-
set_data(request, nil, to_json(cb_data), :create_dir)
|
23
|
+
set_data(request, nil, to_json(cb_data), :create_dir, :create)
|
24
24
|
|
25
|
-
|
25
|
+
already_json_response(201, request.body)
|
26
26
|
end
|
27
27
|
|
28
28
|
# DELETE /organizations/ORG/cookbook_artifacts/COOKBOOK/IDENTIFIER
|
29
29
|
def delete(request)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
delete_data(request)
|
30
|
+
doomed_cookbook_json = get_data(request)
|
31
|
+
identified_cookbook_data = normalize(request, doomed_cookbook_json)
|
32
|
+
delete_data(request)
|
34
33
|
|
35
|
-
|
36
|
-
|
34
|
+
# go through the recipes and delete stuff in the file store.
|
35
|
+
hoover_unused_checksums(get_checksums(doomed_cookbook_json), request)
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
# if this was the last revision, delete the directory so future requests will 404, instead of
|
38
|
+
# returning 200 with an empty list.
|
39
|
+
# Last one out turns out the lights: delete /organizations/ORG/cookbooks/COOKBOOK if it no longer has versions
|
40
|
+
cookbook_path = request.rest_path[0..3]
|
41
|
+
if exists_data_dir?(request, cookbook_path) && list_data(request, cookbook_path).size == 0
|
42
|
+
delete_data_dir(request, cookbook_path)
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
45
|
+
json_response(200, identified_cookbook_data)
|
46
|
+
rescue RestErrorResponse => ex
|
47
|
+
if ex.response_code == 404
|
48
|
+
error(404, "not_found")
|
49
|
+
else
|
50
|
+
raise
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
@@ -99,7 +99,7 @@ module ChefZero
|
|
99
99
|
begin
|
100
100
|
data_store.list(request.rest_path[0..1] + [cookbook_type, cookbook_name]).each do |version|
|
101
101
|
cookbook = data_store.get(request.rest_path[0..1] + [cookbook_type, cookbook_name, version], request)
|
102
|
-
deleted_checksums
|
102
|
+
deleted_checksums -= get_checksums(cookbook)
|
103
103
|
end
|
104
104
|
rescue ChefZero::DataStore::DataNotFoundError
|
105
105
|
end
|
@@ -65,7 +65,7 @@ module ChefZero
|
|
65
65
|
def recipe_names(cookbook_name, cookbook)
|
66
66
|
cookbook["all_files"].inject([]) do |acc, file|
|
67
67
|
part, name = file["name"].split("/")
|
68
|
-
next unless part == "recipes" || File.extname(name) != ".rb"
|
68
|
+
next acc unless part == "recipes" || File.extname(name) != ".rb"
|
69
69
|
if name == "default.rb"
|
70
70
|
acc << cookbook_name
|
71
71
|
else
|
@@ -82,7 +82,7 @@ module ChefZero
|
|
82
82
|
# If the dep is not already in the list, add it to the list to solve
|
83
83
|
# and bring in all environment-allowed cookbook versions to desired_versions
|
84
84
|
if !new_desired_versions.has_key?(dep_name)
|
85
|
-
new_unsolved
|
85
|
+
new_unsolved += [dep_name]
|
86
86
|
# If the dep is missing, we will try other versions of the cookbook that might not have the bad dep.
|
87
87
|
if !exists_data_dir?(request, request.rest_path[0..1] + ["cookbooks", dep_name])
|
88
88
|
@last_missing_dep = dep_name.to_s
|
@@ -101,7 +101,7 @@ module ChefZero
|
|
101
101
|
result = depsolve(request, new_unsolved, new_desired_versions, environment_constraints)
|
102
102
|
return result if result
|
103
103
|
end
|
104
|
-
|
104
|
+
nil
|
105
105
|
end
|
106
106
|
|
107
107
|
def sort_versions(versions)
|
@@ -4,7 +4,7 @@ module ChefZero
|
|
4
4
|
module Endpoints
|
5
5
|
class NotFoundEndpoint
|
6
6
|
def call(request)
|
7
|
-
|
7
|
+
[404, { "Content-Type" => "application/json" }, FFI_Yajl::Encoder.encode({ "error" => ["Object not found: #{request.env['REQUEST_PATH']}"] }, :pretty => true)]
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
@@ -8,7 +8,7 @@ module ChefZero
|
|
8
8
|
def get(request)
|
9
9
|
revisions = list_data(request, request.rest_path + ["revisions"])
|
10
10
|
data = { revisions: hashify_list(revisions) }
|
11
|
-
|
11
|
+
json_response(200, data)
|
12
12
|
end
|
13
13
|
|
14
14
|
# DELETE /organizations/ORG/policies/NAME
|
@@ -17,7 +17,7 @@ module ChefZero
|
|
17
17
|
data = { revisions: hashify_list(revisions) }
|
18
18
|
|
19
19
|
delete_data_dir(request, nil, :recursive)
|
20
|
-
|
20
|
+
json_response(200, data)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -76,7 +76,7 @@ module ChefZero
|
|
76
76
|
|
77
77
|
full_policy_doc = parse_json(get_data(request, policy_path))
|
78
78
|
full_policy_doc = ChefData::DataNormalizer.normalize_policy(full_policy_doc, policy_name, current_revision_id)
|
79
|
-
|
79
|
+
json_response(200, full_policy_doc)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -8,7 +8,7 @@ module ChefZero
|
|
8
8
|
def get(request)
|
9
9
|
data = parse_json(get_data(request))
|
10
10
|
data = ChefData::DataNormalizer.normalize_policy(data, request.rest_path[3], request.rest_path[5])
|
11
|
-
|
11
|
+
json_response(200, data)
|
12
12
|
end
|
13
13
|
|
14
14
|
# DELETE /organizations/ORG/policies/NAME/revisions/REVISION
|
@@ -16,7 +16,7 @@ module ChefZero
|
|
16
16
|
policyfile_data = parse_json(get_data(request))
|
17
17
|
policyfile_data = ChefData::DataNormalizer.normalize_policy(policyfile_data, request.rest_path[3], request.rest_path[5])
|
18
18
|
delete_data(request)
|
19
|
-
|
19
|
+
json_response(200, policyfile_data)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -8,7 +8,7 @@ module ChefZero
|
|
8
8
|
def post(request)
|
9
9
|
policyfile_data = parse_json(request.body)
|
10
10
|
create_data(request, request.rest_path, policyfile_data["revision_id"], request.body, :create_dir)
|
11
|
-
|
11
|
+
already_json_response(201, request.body)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -20,7 +20,7 @@ module ChefZero
|
|
20
20
|
|
21
21
|
def put(request)
|
22
22
|
# We grab the old body to trigger a 404 if it doesn't exist
|
23
|
-
|
23
|
+
get_data(request)
|
24
24
|
|
25
25
|
# If it's a rename, check for conflict and delete the old value
|
26
26
|
if is_rename?(request)
|
@@ -69,7 +69,7 @@ module ChefZero
|
|
69
69
|
|
70
70
|
# Does this request change the value of the identity key?
|
71
71
|
def is_rename?(request)
|
72
|
-
return false unless key = identity_key_value(request)
|
72
|
+
return false unless (key = identity_key_value(request))
|
73
73
|
key != request.rest_path[-1]
|
74
74
|
end
|
75
75
|
end
|
@@ -96,8 +96,8 @@ module ChefZero
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
99
|
-
value.each_pair do |key,
|
100
|
-
result[key] =
|
99
|
+
value.each_pair do |key, val|
|
100
|
+
result[key] = val unless %w{default normal override automatic}.include?(key)
|
101
101
|
end
|
102
102
|
result
|
103
103
|
|
@@ -155,8 +155,6 @@ module ChefZero
|
|
155
155
|
}
|
156
156
|
end
|
157
157
|
|
158
|
-
private
|
159
|
-
|
160
158
|
# Deep Merge core documentation.
|
161
159
|
# deep_merge! method permits merging of arbitrary child elements. The two top level
|
162
160
|
# elements must be hashes. These hashes can contain unlimited (to stack limit) levels
|
@@ -194,7 +192,7 @@ module ChefZero
|
|
194
192
|
end
|
195
193
|
when Array
|
196
194
|
if dest.kind_of?(Array)
|
197
|
-
dest
|
195
|
+
dest |= source
|
198
196
|
else
|
199
197
|
dest = source
|
200
198
|
end
|
data/lib/chef_zero/rest_base.rb
CHANGED
@@ -46,8 +46,8 @@ module ChefZero
|
|
46
46
|
return response unless response.nil?
|
47
47
|
|
48
48
|
method = request.method.downcase.to_sym
|
49
|
-
if !
|
50
|
-
accept_methods = [:get, :put, :post, :delete].select { |m|
|
49
|
+
if !respond_to?(method)
|
50
|
+
accept_methods = [:get, :put, :post, :delete].select { |m| respond_to?(m) }
|
51
51
|
accept_methods_str = accept_methods.map { |m| m.to_s.upcase }.join(", ")
|
52
52
|
return [405, { "Content-Type" => "text/plain", "Allow" => accept_methods_str }, "Bad request method for '#{request.env['REQUEST_PATH']}': #{request.env['REQUEST_METHOD']}"]
|
53
53
|
end
|
@@ -56,7 +56,7 @@ module ChefZero
|
|
56
56
|
end
|
57
57
|
# Dispatch to get()/post()/put()/delete()
|
58
58
|
begin
|
59
|
-
|
59
|
+
send(method, request)
|
60
60
|
rescue RestErrorResponse => e
|
61
61
|
ChefZero::Log.debug("#{e.inspect}\n#{e.backtrace.join("\n")}")
|
62
62
|
error(e.response_code, e.error)
|
@@ -72,7 +72,7 @@ module ChefZero
|
|
72
72
|
# This parses as per http://tools.ietf.org/html/rfc7231#section-5.3
|
73
73
|
return true if !request.env["HTTP_ACCEPT"]
|
74
74
|
accepts = request.env["HTTP_ACCEPT"].split(/,\s*/).map { |x| x.split(";", 2)[0].strip }
|
75
|
-
|
75
|
+
accepts.include?("#{category}/#{type}") || accepts.include?("#{category}/*") || accepts.include?("*/*")
|
76
76
|
end
|
77
77
|
|
78
78
|
def get_data(request, rest_path = nil, *options)
|
@@ -70,7 +70,7 @@ module ChefZero
|
|
70
70
|
def to_s
|
71
71
|
result = "#{method} #{rest_path.join('/')}"
|
72
72
|
if query_params.size > 0
|
73
|
-
result << "?#{query_params.map { |k, v| "#{k}=#{v}" }.join('&')
|
73
|
+
result << "?#{query_params.map { |k, v| "#{k}=#{v}" }.join('&')}"
|
74
74
|
end
|
75
75
|
if body.chomp != ""
|
76
76
|
result << "\n--- #{method} BODY ---\n"
|
data/lib/chef_zero/rspec.rb
CHANGED
@@ -48,6 +48,7 @@ module ChefZero
|
|
48
48
|
|
49
49
|
# Take the passed-in options
|
50
50
|
|
51
|
+
# rubocop:disable Lint/UnderscorePrefixedVariableName
|
51
52
|
define_singleton_method(:chef_server_options) do
|
52
53
|
@chef_server_options ||= begin
|
53
54
|
_chef_server_options = { port: 8900, signals: false, log_requests: true }
|
@@ -55,11 +56,12 @@ module ChefZero
|
|
55
56
|
_chef_server_options = _chef_server_options.freeze
|
56
57
|
end
|
57
58
|
end
|
59
|
+
# rubocop:enable Lint/UnderscorePrefixedVariableName
|
58
60
|
|
59
61
|
# Merge in chef_server_options from let(:chef_server_options)
|
60
|
-
def chef_server_options
|
62
|
+
def chef_server_options # rubocop:disable Lint/NestedMethodDefinition
|
61
63
|
chef_server_options = self.class.chef_server_options.dup
|
62
|
-
chef_server_options = chef_server_options.merge(chef_zero_opts) if
|
64
|
+
chef_server_options = chef_server_options.merge(chef_zero_opts) if respond_to?(:chef_zero_opts)
|
63
65
|
chef_server_options
|
64
66
|
end
|
65
67
|
|
data/lib/chef_zero/server.rb
CHANGED
@@ -493,7 +493,7 @@ module ChefZero
|
|
493
493
|
if contents[cookbook_type]
|
494
494
|
contents[cookbook_type].each_pair do |name_version, cookbook|
|
495
495
|
if cookbook_type == "cookbook_artifacts"
|
496
|
-
name,
|
496
|
+
name, _, identifier = name_version.rpartition("-")
|
497
497
|
cookbook_data = ChefData::CookbookData.to_hash(cookbook, name, identifier)
|
498
498
|
elsif name_version =~ /(.+)-(\d+\.\d+\.\d+)$/
|
499
499
|
cookbook_data = ChefData::CookbookData.to_hash(cookbook, $1, $2)
|
data/lib/chef_zero/version.rb
CHANGED
data/spec/run_oc_pedant.rb
CHANGED
@@ -49,12 +49,12 @@ def start_cheffs_server(chef_repo_path)
|
|
49
49
|
require "chef/chef_fs/chef_fs_data_store"
|
50
50
|
require "chef_zero/server"
|
51
51
|
|
52
|
-
Dir.mkdir(chef_repo_path) if !File.
|
52
|
+
Dir.mkdir(chef_repo_path) if !File.exist?(chef_repo_path)
|
53
53
|
|
54
54
|
# 11.6 and below had a bug where it couldn't create the repo children automatically
|
55
55
|
if Chef::VERSION.to_f < 11.8
|
56
56
|
%w{clients cookbooks data_bags environments nodes roles users}.each do |child|
|
57
|
-
Dir.mkdir("#{chef_repo_path}/#{child}") if !File.
|
57
|
+
Dir.mkdir("#{chef_repo_path}/#{child}") if !File.exist?("#{chef_repo_path}/#{child}")
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
data/spec/search_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-zero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 14.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixlib-log
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: hashie
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -296,7 +296,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
296
296
|
requirements:
|
297
297
|
- - ">="
|
298
298
|
- !ruby/object:Gem::Version
|
299
|
-
version: 2.3
|
299
|
+
version: 2.4.3
|
300
300
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
301
301
|
requirements:
|
302
302
|
- - ">="
|
@@ -304,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
304
|
version: '0'
|
305
305
|
requirements: []
|
306
306
|
rubyforge_project:
|
307
|
-
rubygems_version: 2.
|
307
|
+
rubygems_version: 2.7.3
|
308
308
|
signing_key:
|
309
309
|
specification_version: 4
|
310
310
|
summary: Self-contained, easy-setup, fast-start in-memory Chef server for testing
|