chef-cli 1.0.3 → 1.0.6
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 +4 -4
- data/Gemfile +4 -0
- data/chef-cli.gemspec +2 -2
- data/lib/chef-cli/builtin_commands.rb +3 -0
- data/lib/chef-cli/cli.rb +3 -1
- data/lib/chef-cli/command/clean_policy_cookbooks.rb +1 -0
- data/lib/chef-cli/command/clean_policy_revisions.rb +1 -0
- data/lib/chef-cli/command/delete_policy.rb +1 -0
- data/lib/chef-cli/command/delete_policy_group.rb +1 -0
- data/lib/chef-cli/command/describe_cookbook.rb +1 -0
- data/lib/chef-cli/command/diff.rb +5 -3
- data/lib/chef-cli/command/env.rb +3 -3
- data/lib/chef-cli/command/export.rb +1 -0
- data/lib/chef-cli/command/generate.rb +1 -0
- data/lib/chef-cli/command/generator_commands/chef_exts/quieter_doc_formatter.rb +2 -4
- data/lib/chef-cli/command/generator_commands/generator_generator.rb +1 -0
- data/lib/chef-cli/command/install.rb +1 -0
- data/lib/chef-cli/command/push.rb +1 -0
- data/lib/chef-cli/command/push_archive.rb +1 -1
- data/lib/chef-cli/command/shell_init.rb +3 -2
- data/lib/chef-cli/command/show_policy.rb +1 -0
- data/lib/chef-cli/command/undelete.rb +1 -0
- data/lib/chef-cli/command/update.rb +1 -0
- data/lib/chef-cli/component_test.rb +2 -1
- data/lib/chef-cli/configurable.rb +3 -2
- data/lib/chef-cli/cookbook_profiler/null_scm.rb +1 -2
- data/lib/chef-cli/generator.rb +1 -1
- data/lib/chef-cli/helpers.rb +2 -1
- data/lib/chef-cli/policyfile/artifactory_cookbook_source.rb +1 -1
- data/lib/chef-cli/policyfile/attribute_merge_checker.rb +1 -1
- data/lib/chef-cli/policyfile/chef_repo_cookbook_source.rb +1 -1
- data/lib/chef-cli/policyfile/chef_server_cookbook_source.rb +3 -3
- data/lib/chef-cli/policyfile/chef_server_lock_fetcher.rb +5 -5
- data/lib/chef-cli/policyfile/community_cookbook_source.rb +1 -1
- data/lib/chef-cli/policyfile/comparison_base.rb +1 -0
- data/lib/chef-cli/policyfile/cookbook_location_specification.rb +4 -4
- data/lib/chef-cli/policyfile/cookbook_locks.rb +8 -5
- data/lib/chef-cli/policyfile/delivery_supermarket_source.rb +1 -1
- data/lib/chef-cli/policyfile/differ.rb +6 -2
- data/lib/chef-cli/policyfile/dsl.rb +4 -2
- data/lib/chef-cli/policyfile/git_lock_fetcher.rb +2 -2
- data/lib/chef-cli/policyfile/included_policies_cookbook_source.rb +1 -1
- data/lib/chef-cli/policyfile/lister.rb +2 -2
- data/lib/chef-cli/policyfile/local_lock_fetcher.rb +7 -5
- data/lib/chef-cli/policyfile/lock_applier.rb +1 -1
- data/lib/chef-cli/policyfile/null_cookbook_source.rb +1 -2
- data/lib/chef-cli/policyfile/policyfile_location_specification.rb +3 -3
- data/lib/chef-cli/policyfile/remote_lock_fetcher.rb +1 -1
- data/lib/chef-cli/policyfile/solution_dependencies.rb +13 -11
- data/lib/chef-cli/policyfile/storage_config.rb +1 -0
- data/lib/chef-cli/policyfile/undo_record.rb +10 -8
- data/lib/chef-cli/policyfile/uploader.rb +3 -1
- data/lib/chef-cli/policyfile_compiler.rb +17 -13
- data/lib/chef-cli/policyfile_lock.rb +17 -15
- data/lib/chef-cli/policyfile_services/clean_policies.rb +3 -3
- data/lib/chef-cli/policyfile_services/clean_policy_cookbooks.rb +2 -2
- data/lib/chef-cli/policyfile_services/export_repo.rb +4 -2
- data/lib/chef-cli/policyfile_services/install.rb +3 -1
- data/lib/chef-cli/policyfile_services/push.rb +6 -5
- data/lib/chef-cli/policyfile_services/push_archive.rb +6 -5
- data/lib/chef-cli/policyfile_services/rm_policy.rb +6 -2
- data/lib/chef-cli/policyfile_services/rm_policy_group.rb +2 -2
- data/lib/chef-cli/policyfile_services/show_policy.rb +2 -2
- data/lib/chef-cli/policyfile_services/undelete.rb +2 -2
- data/lib/chef-cli/version.rb +1 -1
- data/lib/kitchen/provisioner/policyfile_zero.rb +3 -6
- data/spec/unit/cli_spec.rb +5 -5
- data/spec/unit/command/base_spec.rb +1 -1
- data/spec/unit/command/env_spec.rb +1 -1
- data/spec/unit/command/exec_spec.rb +1 -1
- data/spec/unit/command/export_spec.rb +1 -1
- data/spec/unit/command/generator_commands/recipe_spec.rb +2 -1
- data/spec/unit/command/generator_commands/repo_spec.rb +6 -6
- data/spec/unit/command/verify_spec.rb +1 -1
- data/spec/unit/policyfile/attribute_merge_checker_spec.rb +10 -8
- data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +4 -2
- data/spec/unit/policyfile/cookbook_locks_spec.rb +9 -9
- data/spec/unit/policyfile/git_lock_fetcher_spec.rb +5 -5
- data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +5 -3
- data/spec/unit/policyfile/lister_spec.rb +5 -5
- data/spec/unit/policyfile/local_lock_fetcher_spec.rb +1 -1
- data/spec/unit/policyfile/lock_applier_spec.rb +2 -2
- data/spec/unit/policyfile/reports/install_spec.rb +14 -14
- data/spec/unit/policyfile/reports/upload_spec.rb +3 -3
- data/spec/unit/policyfile/uploader_spec.rb +13 -12
- data/spec/unit/policyfile_demands_spec.rb +4 -4
- data/spec/unit/policyfile_includes_spec.rb +14 -7
- data/spec/unit/policyfile_install_with_includes_spec.rb +8 -7
- data/spec/unit/policyfile_lock_build_spec.rb +17 -18
- data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +5 -5
- data/spec/unit/policyfile_services/push_archive_spec.rb +6 -6
- data/spec/unit/policyfile_services/push_spec.rb +8 -8
- data/spec/unit/policyfile_services/rm_policy_group_spec.rb +5 -5
- data/spec/unit/policyfile_services/rm_policy_spec.rb +5 -5
- data/spec/unit/policyfile_services/update_attributes_spec.rb +2 -1
- data/spec/unit/service_exception_inspectors/http_spec.rb +7 -7
- metadata +7 -7
@@ -27,7 +27,7 @@ module ChefCLI
|
|
27
27
|
module Policyfile
|
28
28
|
class DSL
|
29
29
|
|
30
|
-
RUN_LIST_ITEM_COMPONENT =
|
30
|
+
RUN_LIST_ITEM_COMPONENT = /^[.[:alnum:]_-]+$/.freeze
|
31
31
|
|
32
32
|
include StorageConfigDelegation
|
33
33
|
|
@@ -86,6 +86,7 @@ module ChefCLI
|
|
86
86
|
|
87
87
|
def default_source(source_type = nil, source_argument = nil, &block)
|
88
88
|
return @default_source if source_type.nil?
|
89
|
+
|
89
90
|
case source_type
|
90
91
|
when :community, :supermarket
|
91
92
|
set_default_community_source(source_argument, &block)
|
@@ -252,7 +253,8 @@ module ChefCLI
|
|
252
253
|
default_source.combination(2).each do |source_a, source_b|
|
253
254
|
conflicting_preferences = source_a.preferred_cookbooks & source_b.preferred_cookbooks
|
254
255
|
next if conflicting_preferences.empty?
|
255
|
-
|
256
|
+
|
257
|
+
conflicting_source_messages << "#{source_a.desc} and #{source_b.desc} are both set as the preferred source for cookbook(s) '#{conflicting_preferences.join(", ")}'"
|
256
258
|
end
|
257
259
|
unless conflicting_source_messages.empty?
|
258
260
|
msg = "Multiple sources are marked as the preferred source for some cookbooks. Only one source can be preferred for a cookbook.\n"
|
@@ -98,7 +98,7 @@ module ChefCLI
|
|
98
98
|
acc
|
99
99
|
end
|
100
100
|
source_options.merge!(options)
|
101
|
-
raise ChefCLI::InvalidLockfile, "Invalid source_options provided from lock data: #{options_from_lock_file.inspect}"
|
101
|
+
raise ChefCLI::InvalidLockfile, "Invalid source_options provided from lock data: #{options_from_lock_file.inspect}" unless valid?
|
102
102
|
end
|
103
103
|
|
104
104
|
# @return [Hash] of the policyfile lock data
|
@@ -126,7 +126,7 @@ module ChefCLI
|
|
126
126
|
# as a git repo and not a local directory. Git also doesn't like paths
|
127
127
|
# prefixed with `./` and cannot use relative paths outside the repo.
|
128
128
|
# http://rubular.com/r/JYpdYHT19p
|
129
|
-
pattern =
|
129
|
+
pattern = %r{(^../)|(^./)}
|
130
130
|
opt["rel"] = opt[name].gsub(pattern, "")
|
131
131
|
end
|
132
132
|
|
@@ -69,7 +69,7 @@ module ChefCLI
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def ==(other)
|
72
|
-
other.
|
72
|
+
other.is_a?(self.class) && other.included_policy_location_specs == included_policy_location_specs
|
73
73
|
end
|
74
74
|
|
75
75
|
# Calls the slurp_metadata! helper once to calculate the @universe_graph
|
@@ -184,8 +184,8 @@ module ChefCLI
|
|
184
184
|
|
185
185
|
def http_client
|
186
186
|
@http_client ||= Chef::ServerAPI.new(config.chef_server_url,
|
187
|
-
|
188
|
-
|
187
|
+
signing_key_filename: config.client_key,
|
188
|
+
client_name: config.node_name)
|
189
189
|
end
|
190
190
|
|
191
191
|
# @api private
|
@@ -80,7 +80,7 @@ module ChefCLI
|
|
80
80
|
validate_revision_id(data["revision_id"], source_options)
|
81
81
|
data["cookbook_locks"].each do |cookbook_name, cookbook_lock|
|
82
82
|
cookbook_path = cookbook_lock["source_options"]["path"]
|
83
|
-
|
83
|
+
unless cookbook_path.nil?
|
84
84
|
cookbook_lock["source_options"]["path"] = transform_path(cookbook_path)
|
85
85
|
end
|
86
86
|
end
|
@@ -110,14 +110,16 @@ module ChefCLI
|
|
110
110
|
path = abs_path
|
111
111
|
if path.directory?
|
112
112
|
path = path.join("#{name}.lock.json")
|
113
|
-
|
113
|
+
unless path.file?
|
114
114
|
raise ChefCLI::LocalPolicyfileLockNotFound.new(
|
115
|
-
"Expected to find file #{name}.lock.json inside #{source_options[:path]}. If the file name is different than this, provide the file name as part of the path."
|
115
|
+
"Expected to find file #{name}.lock.json inside #{source_options[:path]}. If the file name is different than this, provide the file name as part of the path."
|
116
|
+
)
|
116
117
|
end
|
117
118
|
else
|
118
|
-
|
119
|
+
unless path.file?
|
119
120
|
raise ChefCLI::LocalPolicyfileLockNotFound.new(
|
120
|
-
"The provided path #{source_options[:path]} does not exist."
|
121
|
+
"The provided path #{source_options[:path]} does not exist."
|
122
|
+
)
|
121
123
|
end
|
122
124
|
end
|
123
125
|
path
|
@@ -67,7 +67,7 @@ module ChefCLI
|
|
67
67
|
end
|
68
68
|
|
69
69
|
policyfile_compiler.included_policies.each do |policy|
|
70
|
-
|
70
|
+
unless unlocked_policies.include?(policy.name)
|
71
71
|
lock = policyfile_lock.included_policy_locks.find do |policy_lock|
|
72
72
|
policy_lock["name"] == policy.name
|
73
73
|
end
|
@@ -38,7 +38,7 @@ module ChefCLI
|
|
38
38
|
attr_reader :chef_config
|
39
39
|
attr_reader :ui
|
40
40
|
|
41
|
-
LOCATION_TYPES =
|
41
|
+
LOCATION_TYPES = %i{path remote server git}.freeze
|
42
42
|
|
43
43
|
# Initialize a location spec
|
44
44
|
#
|
@@ -92,9 +92,9 @@ module ChefCLI
|
|
92
92
|
error_messages = []
|
93
93
|
|
94
94
|
if LOCATION_TYPES.all? { |l| source_options[l].nil? }
|
95
|
-
error_messages << "include_policy must use one of the following sources: #{LOCATION_TYPES.join(
|
95
|
+
error_messages << "include_policy must use one of the following sources: #{LOCATION_TYPES.join(", ")}"
|
96
96
|
else
|
97
|
-
|
97
|
+
unless fetcher.nil?
|
98
98
|
error_messages += fetcher.errors
|
99
99
|
end
|
100
100
|
end
|
@@ -79,7 +79,7 @@ module ChefCLI
|
|
79
79
|
validate_revision_id(data["revision_id"], source_options)
|
80
80
|
data["cookbook_locks"].each do |cookbook_name, cookbook_lock|
|
81
81
|
cookbook_path = cookbook_lock["source_options"]["path"]
|
82
|
-
|
82
|
+
unless cookbook_path.nil?
|
83
83
|
raise ChefCLI::InvalidLockfile, "Invalid cookbook path: #{cookbook_path}. Remote Policyfiles should only use remote cookbooks."
|
84
84
|
end
|
85
85
|
end
|
@@ -45,7 +45,7 @@ module ChefCLI
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def eql?(other)
|
48
|
-
other.
|
48
|
+
other.is_a?(self.class) &&
|
49
49
|
other.name == name &&
|
50
50
|
other.version == version
|
51
51
|
end
|
@@ -127,6 +127,7 @@ module ChefCLI
|
|
127
127
|
until to_explore.empty?
|
128
128
|
ck_name = to_explore.shift
|
129
129
|
next unless deps.add?(ck_name) # explore each ck only once
|
130
|
+
|
130
131
|
my_deps = find_cookbook_dep_by_name(ck_name)
|
131
132
|
dep_names = my_deps[1].map(&:first)
|
132
133
|
to_explore += dep_names
|
@@ -158,6 +159,7 @@ module ChefCLI
|
|
158
159
|
def assert_cookbook_deps_valid!(cookbook_name, version)
|
159
160
|
dependency_conflicts = cookbook_deps_conflicts_for(cookbook_name, version)
|
160
161
|
return false if dependency_conflicts.empty?
|
162
|
+
|
161
163
|
message = "Cookbook #{cookbook_name} (#{version}) has dependency constraints that cannot be met by the existing cookbook set:\n"
|
162
164
|
full_message = message + dependency_conflicts.join("\n")
|
163
165
|
raise DependencyConflict, full_message
|
@@ -218,7 +220,7 @@ module ChefCLI
|
|
218
220
|
def set_policyfile_deps_from_lock_data(lock_data)
|
219
221
|
policyfile_deps_data = lock_data["Policyfile"]
|
220
222
|
|
221
|
-
unless policyfile_deps_data.
|
223
|
+
unless policyfile_deps_data.is_a?(Array)
|
222
224
|
msg = "lockfile solution_dependencies Policyfile dependencies must be an array of cookbooks and constraints (got: #{policyfile_deps_data.inspect})"
|
223
225
|
raise InvalidLockfile, msg
|
224
226
|
end
|
@@ -229,19 +231,19 @@ module ChefCLI
|
|
229
231
|
end
|
230
232
|
|
231
233
|
def add_policyfile_dep_from_lock_data(entry)
|
232
|
-
unless entry.
|
234
|
+
unless entry.is_a?(Array) && entry.size == 2
|
233
235
|
msg = %Q{lockfile solution_dependencies Policyfile dependencies entry must be like [ "$COOKBOOK_NAME", "$CONSTRAINT" ] (got: #{entry.inspect})}
|
234
236
|
raise InvalidLockfile, msg
|
235
237
|
end
|
236
238
|
|
237
239
|
cookbook_name, constraint = entry
|
238
240
|
|
239
|
-
unless cookbook_name.
|
241
|
+
unless cookbook_name.is_a?(String) && !cookbook_name.empty?
|
240
242
|
msg = "lockfile solution_dependencies Policyfile dependencies entry. Cookbook name portion must be a string (got: #{entry.inspect})"
|
241
243
|
raise InvalidLockfile, msg
|
242
244
|
end
|
243
245
|
|
244
|
-
unless constraint.
|
246
|
+
unless constraint.is_a?(String) && !constraint.empty?
|
245
247
|
msg = "malformed lockfile solution_dependencies Policyfile dependencies entry. Version constraint portion must be a string (got: #{entry.inspect})"
|
246
248
|
raise InvalidLockfile, msg
|
247
249
|
end
|
@@ -254,7 +256,7 @@ module ChefCLI
|
|
254
256
|
def set_cookbook_deps_from_lock_data(lock_data)
|
255
257
|
cookbook_dependencies_data = lock_data["dependencies"]
|
256
258
|
|
257
|
-
unless cookbook_dependencies_data.
|
259
|
+
unless cookbook_dependencies_data.is_a?(Hash)
|
258
260
|
msg = "lockfile solution_dependencies dependencies entry must be a Hash (JSON object) of dependencies (got: #{cookbook_dependencies_data.inspect})"
|
259
261
|
raise InvalidLockfile, msg
|
260
262
|
end
|
@@ -265,7 +267,7 @@ module ChefCLI
|
|
265
267
|
end
|
266
268
|
|
267
269
|
def add_cookbook_dep_from_lock_data(name_and_version, deps_list)
|
268
|
-
unless name_and_version.
|
270
|
+
unless name_and_version.is_a?(String)
|
269
271
|
show = "#{name_and_version.inspect} => #{deps_list.inspect}"
|
270
272
|
msg = %Q{lockfile cookbook_dependencies entries must be of the form "$COOKBOOK_NAME ($VERSION)" => [ $dependency, ...] (got: #{show}) }
|
271
273
|
raise InvalidLockfile, msg
|
@@ -276,26 +278,26 @@ module ChefCLI
|
|
276
278
|
raise InvalidLockfile, msg
|
277
279
|
end
|
278
280
|
|
279
|
-
unless deps_list.
|
281
|
+
unless deps_list.is_a?(Array)
|
280
282
|
msg = %Q{lockfile cookbook_dependencies entry values must be an Array like [ [ "$COOKBOOK_NAME", "$CONSTRAINT" ], ... ] (got: #{deps_list.inspect}) }
|
281
283
|
raise InvalidLockfile, msg
|
282
284
|
end
|
283
285
|
|
284
286
|
deps_list.each do |entry|
|
285
287
|
|
286
|
-
unless entry.
|
288
|
+
unless entry.is_a?(Array) && entry.size == 2
|
287
289
|
msg = %Q{lockfile solution_dependencies dependencies entry must be like [ "$COOKBOOK_NAME", "$CONSTRAINT" ] (got: #{entry.inspect})}
|
288
290
|
raise InvalidLockfile, msg
|
289
291
|
end
|
290
292
|
|
291
293
|
dep_name, constraint = entry
|
292
294
|
|
293
|
-
unless dep_name.
|
295
|
+
unless dep_name.is_a?(String) && !dep_name.empty?
|
294
296
|
msg = "malformed lockfile solution_dependencies dependencies entry. Cookbook name portion must be a string (got: #{entry.inspect})"
|
295
297
|
raise InvalidLockfile, msg
|
296
298
|
end
|
297
299
|
|
298
|
-
unless constraint.
|
300
|
+
unless constraint.is_a?(String) && !constraint.empty?
|
299
301
|
msg = "malformed lockfile solution_dependencies dependencies entry. Version constraint portion must be a string (got: #{entry.inspect})"
|
300
302
|
raise InvalidLockfile, msg
|
301
303
|
end
|
@@ -54,6 +54,7 @@ module ChefCLI
|
|
54
54
|
unless policyfile_filename.end_with?(".rb")
|
55
55
|
raise InvalidPolicyfileFilename, "Policyfile filenames must end with `.rb' extension (you gave: `#{policyfile_filename}')"
|
56
56
|
end
|
57
|
+
|
57
58
|
@policyfile_filename = policyfile_filename
|
58
59
|
@policyfile_lock_filename = policyfile_filename.sub(/\.rb\Z/, ".lock.json")
|
59
60
|
@relative_paths_root = File.dirname(policyfile_filename)
|
@@ -52,7 +52,7 @@ module ChefCLI
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def ==(other)
|
55
|
-
other.
|
55
|
+
other.is_a?(UndoRecord) &&
|
56
56
|
other.policy_groups == policy_groups &&
|
57
57
|
other.policy_revisions == policy_revisions
|
58
58
|
end
|
@@ -68,29 +68,31 @@ module ChefCLI
|
|
68
68
|
def load(data)
|
69
69
|
reset!
|
70
70
|
|
71
|
-
unless data.
|
71
|
+
unless data.is_a?(Hash)
|
72
72
|
raise InvalidUndoRecord, "Undo data is incorrectly formatted. Must be a Hash, got '#{data}'."
|
73
73
|
end
|
74
|
+
|
74
75
|
missing_fields = %w{ format_version description backup_data }.select { |key| !data.key?(key) }
|
75
76
|
unless missing_fields.empty?
|
76
|
-
raise InvalidUndoRecord, "Undo data is missing mandatory field(s) #{missing_fields.join(
|
77
|
+
raise InvalidUndoRecord, "Undo data is missing mandatory field(s) #{missing_fields.join(", ")}. Undo data: '#{data}'"
|
77
78
|
end
|
78
79
|
|
79
80
|
@description = data["description"]
|
80
81
|
|
81
82
|
policy_data = data["backup_data"]
|
82
|
-
unless policy_data.
|
83
|
+
unless policy_data.is_a?(Hash)
|
83
84
|
raise InvalidUndoRecord, "'backup_data' in the undo record is incorrectly formatted. Must be a Hash, got '#{policy_data}'"
|
84
85
|
end
|
86
|
+
|
85
87
|
missing_policy_data_fields = %w{ policy_groups policy_revisions }.select { |key| !policy_data.key?(key) }
|
86
88
|
unless missing_policy_data_fields.empty?
|
87
89
|
raise InvalidUndoRecord,
|
88
|
-
"'backup_data' in the undo record is missing mandatory field(s) #{missing_policy_data_fields.join(
|
90
|
+
"'backup_data' in the undo record is missing mandatory field(s) #{missing_policy_data_fields.join(", ")}. Backup data: #{policy_data}"
|
89
91
|
end
|
90
92
|
|
91
93
|
policy_groups = policy_data["policy_groups"]
|
92
94
|
|
93
|
-
unless policy_groups.
|
95
|
+
unless policy_groups.is_a?(Array)
|
94
96
|
raise InvalidUndoRecord,
|
95
97
|
"'policy_groups' data in the undo record is incorrectly formatted. Must be an Array, got '#{policy_groups}'"
|
96
98
|
end
|
@@ -98,13 +100,13 @@ module ChefCLI
|
|
98
100
|
@policy_groups = policy_groups
|
99
101
|
|
100
102
|
policy_revisions = policy_data["policy_revisions"]
|
101
|
-
unless policy_revisions.
|
103
|
+
unless policy_revisions.is_a?(Array)
|
102
104
|
raise InvalidUndoRecord,
|
103
105
|
"'policy_revisions' data in the undo record is incorrectly formatted. Must be an Array, got '#{policy_revisions}'"
|
104
106
|
end
|
105
107
|
|
106
108
|
policy_revisions.each do |revision|
|
107
|
-
unless revision.
|
109
|
+
unless revision.is_a?(Hash)
|
108
110
|
raise InvalidUndoRecord,
|
109
111
|
"Invalid item in 'policy_revisions' in the undo record. Must be a Hash, got '#{revision}'"
|
110
112
|
end
|
@@ -52,7 +52,7 @@ module ChefCLI
|
|
52
52
|
def upload
|
53
53
|
ui.msg("Uploading policy #{policy_name} (#{short_revision_id}) to policy group #{policy_group}")
|
54
54
|
|
55
|
-
|
55
|
+
unless using_policy_document_native_api?
|
56
56
|
ui.msg(<<~DRAGONS)
|
57
57
|
WARN: Uploading policy to policy group #{policy_group} in compatibility mode.
|
58
58
|
Cookbooks will be uploaded with very large version numbers, which may be picked
|
@@ -152,6 +152,7 @@ module ChefCLI
|
|
152
152
|
# the policyfile lock requires.
|
153
153
|
def cookbook_versions_for_policy
|
154
154
|
return @cookbook_versions_for_policy if @cookbook_versions_for_policy
|
155
|
+
|
155
156
|
policyfile_lock.validate_cookbooks!
|
156
157
|
@cookbook_versions_for_policy =
|
157
158
|
if using_policy_document_native_api?
|
@@ -215,6 +216,7 @@ module ChefCLI
|
|
215
216
|
http_client.put("data/#{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}", data_item)
|
216
217
|
rescue Net::HTTPServerException => e
|
217
218
|
raise e unless e.response.code == "404"
|
219
|
+
|
218
220
|
http_client.post("data/#{COMPAT_MODE_DATA_BAG_NAME}", data_item)
|
219
221
|
end
|
220
222
|
end
|
@@ -39,7 +39,7 @@ module ChefCLI
|
|
39
39
|
DEFAULT_DEMAND_CONSTRAINT = ">= 0.0.0".freeze
|
40
40
|
|
41
41
|
# Cookbooks from these sources lock that cookbook to exactly one version
|
42
|
-
SOURCE_TYPES_WITH_FIXED_VERSIONS =
|
42
|
+
SOURCE_TYPES_WITH_FIXED_VERSIONS = %i{git path}.freeze
|
43
43
|
|
44
44
|
def self.evaluate(policyfile_string, policyfile_filename, ui: nil, chef_config: nil)
|
45
45
|
compiler = new(ui: ui, chef_config: chef_config)
|
@@ -144,18 +144,20 @@ module ChefCLI
|
|
144
144
|
|
145
145
|
def default_attributes
|
146
146
|
check_for_default_attribute_conflicts!
|
147
|
-
included_policies.map
|
148
|
-
dsl.node_attributes.combined_default.to_hash
|
149
|
-
|
150
|
-
|
147
|
+
included_policies.map(&:policyfile_lock).inject(
|
148
|
+
dsl.node_attributes.combined_default.to_hash
|
149
|
+
) do |acc, lock|
|
150
|
+
Chef::Mixin::DeepMerge.merge(acc, lock.default_attributes)
|
151
|
+
end
|
151
152
|
end
|
152
153
|
|
153
154
|
def override_attributes
|
154
155
|
check_for_override_attribute_conflicts!
|
155
|
-
included_policies.map
|
156
|
-
dsl.node_attributes.combined_override.to_hash
|
157
|
-
|
158
|
-
|
156
|
+
included_policies.map(&:policyfile_lock).inject(
|
157
|
+
dsl.node_attributes.combined_override.to_hash
|
158
|
+
) do |acc, lock|
|
159
|
+
Chef::Mixin::DeepMerge.merge(acc, lock.override_attributes)
|
160
|
+
end
|
159
161
|
end
|
160
162
|
|
161
163
|
def lock
|
@@ -225,6 +227,7 @@ module ChefCLI
|
|
225
227
|
|
226
228
|
def graph_solution
|
227
229
|
return @solution if @solution
|
230
|
+
|
228
231
|
cache_fixed_version_cookbooks
|
229
232
|
@solution = Solve.it!(graph, graph_demands)
|
230
233
|
end
|
@@ -322,7 +325,7 @@ module ChefCLI
|
|
322
325
|
end
|
323
326
|
|
324
327
|
def cookbooks_in_run_list
|
325
|
-
recipes = combined_run_lists.map
|
328
|
+
recipes = combined_run_lists.map(&:name)
|
326
329
|
recipes.map { |r| r[/^([^:]+)/, 1] }
|
327
330
|
end
|
328
331
|
|
@@ -443,7 +446,7 @@ module ChefCLI
|
|
443
446
|
deps_by_version = source.universe_graph[cookbook_name]
|
444
447
|
|
445
448
|
dep_cookbook_names = deps_by_version.values.inject(Set.new) do |names, constraint_list|
|
446
|
-
names.merge(constraint_list.map
|
449
|
+
names.merge(constraint_list.map(&:first))
|
447
450
|
end
|
448
451
|
|
449
452
|
dep_cookbook_names.each do |dep_cookbook_name|
|
@@ -504,7 +507,7 @@ module ChefCLI
|
|
504
507
|
def handle_included_policies_preferred_cookbook_conflicts(included_policies_source)
|
505
508
|
# All cookbooks in the included policies are preferred.
|
506
509
|
conflicting_source_messages = []
|
507
|
-
dsl.default_source.reject
|
510
|
+
dsl.default_source.reject(&:null?).each do |source_b|
|
508
511
|
conflicting_preferences = included_policies_source.preferred_cookbooks & source_b.preferred_cookbooks
|
509
512
|
next if conflicting_preferences.empty?
|
510
513
|
next if conflicting_preferences.all? do |cookbook_name|
|
@@ -515,7 +518,8 @@ module ChefCLI
|
|
515
518
|
false
|
516
519
|
end
|
517
520
|
end
|
518
|
-
|
521
|
+
|
522
|
+
conflicting_source_messages << "#{source_b.desc} sets a preferred for cookbook(s) #{conflicting_preferences.join(", ")}. This conflicts with an included policy."
|
519
523
|
end
|
520
524
|
unless conflicting_source_messages.empty?
|
521
525
|
msg = "You may not override the cookbook sources for any cookbooks required by included policies.\n"
|
@@ -321,9 +321,10 @@ module ChefCLI
|
|
321
321
|
# Recursive, so absurd nesting levels could cause a SystemError. Invalid
|
322
322
|
# input will cause an InvalidPolicyfileAttribute exception.
|
323
323
|
def canonicalize(attributes)
|
324
|
-
unless attributes.
|
324
|
+
unless attributes.is_a?(Hash)
|
325
325
|
raise "Top level attributes must be a Hash (you gave: #{attributes})"
|
326
326
|
end
|
327
|
+
|
327
328
|
canonicalize_elements(attributes)
|
328
329
|
end
|
329
330
|
|
@@ -355,6 +356,7 @@ module ChefCLI
|
|
355
356
|
unless item.finite?
|
356
357
|
raise InvalidPolicyfileAttribute, "Floating point numbers cannot be infinite or NaN. You gave #{item.inspect}"
|
357
358
|
end
|
359
|
+
|
358
360
|
# Support for floats assumes that any implementation of our JSON
|
359
361
|
# canonicalization routine will use IEEE-754 doubles. In decimal terms,
|
360
362
|
# doubles give 15-17 digits of precision, so we err on the safe side
|
@@ -392,7 +394,7 @@ module ChefCLI
|
|
392
394
|
end
|
393
395
|
|
394
396
|
def validate_attr_key(key)
|
395
|
-
unless key.
|
397
|
+
unless key.is_a?(String)
|
396
398
|
raise InvalidPolicyfileAttribute,
|
397
399
|
"Attribute keys must be Strings (other types are not allowed in JSON). You gave: #{key.inspect} (#{key.class})"
|
398
400
|
end
|
@@ -403,7 +405,7 @@ module ChefCLI
|
|
403
405
|
|
404
406
|
raise InvalidLockfile, "lockfile does not have a `name' attribute" if name_attribute.nil?
|
405
407
|
|
406
|
-
unless name_attribute.
|
408
|
+
unless name_attribute.is_a?(String)
|
407
409
|
raise InvalidLockfile, "lockfile's name attribute must be a String (got: #{name_attribute.inspect})"
|
408
410
|
end
|
409
411
|
|
@@ -419,7 +421,7 @@ module ChefCLI
|
|
419
421
|
|
420
422
|
raise InvalidLockfile, "lockfile does not have a run_list attribute" if run_list_attribute.nil?
|
421
423
|
|
422
|
-
unless run_list_attribute.
|
424
|
+
unless run_list_attribute.is_a?(Array)
|
423
425
|
raise InvalidLockfile, "lockfile's run_list must be an array of run list items (got: #{run_list_attribute.inspect})"
|
424
426
|
end
|
425
427
|
|
@@ -438,17 +440,17 @@ module ChefCLI
|
|
438
440
|
|
439
441
|
lock_data_named_run_lists = lock_data["named_run_lists"]
|
440
442
|
|
441
|
-
unless lock_data_named_run_lists.
|
443
|
+
unless lock_data_named_run_lists.is_a?(Hash)
|
442
444
|
msg = "lockfile's named_run_lists must be a Hash (JSON object). (got: #{lock_data_named_run_lists.inspect})"
|
443
445
|
raise InvalidLockfile, msg
|
444
446
|
end
|
445
447
|
|
446
448
|
lock_data_named_run_lists.each do |name, run_list|
|
447
|
-
unless name.
|
449
|
+
unless name.is_a?(String)
|
448
450
|
msg = "Keys in lockfile's named_run_lists must be Strings. (got: #{name.inspect})"
|
449
451
|
raise InvalidLockfile, msg
|
450
452
|
end
|
451
|
-
unless run_list.
|
453
|
+
unless run_list.is_a?(Array)
|
452
454
|
msg = "Values in lockfile's named_run_lists must be Arrays. (got: #{run_list.inspect})"
|
453
455
|
raise InvalidLockfile, msg
|
454
456
|
end
|
@@ -468,7 +470,7 @@ module ChefCLI
|
|
468
470
|
raise InvalidLockfile, "lockfile does not have a cookbook_locks attribute"
|
469
471
|
end
|
470
472
|
|
471
|
-
unless cookbook_lock_data.
|
473
|
+
unless cookbook_lock_data.is_a?(Hash)
|
472
474
|
raise InvalidLockfile, "lockfile's cookbook_locks attribute must be a Hash (JSON object). (got: #{cookbook_lock_data.inspect})"
|
473
475
|
end
|
474
476
|
|
@@ -484,7 +486,7 @@ module ChefCLI
|
|
484
486
|
raise InvalidLockfile, "lockfile does not have a cookbook_locks attribute"
|
485
487
|
end
|
486
488
|
|
487
|
-
unless cookbook_lock_data.
|
489
|
+
unless cookbook_lock_data.is_a?(Hash)
|
488
490
|
raise InvalidLockfile, "lockfile's cookbook_locks attribute must be a Hash (JSON object). (got: #{cookbook_lock_data.inspect})"
|
489
491
|
end
|
490
492
|
|
@@ -500,7 +502,7 @@ module ChefCLI
|
|
500
502
|
raise InvalidLockfile, "lockfile does not have a `default_attributes` attribute"
|
501
503
|
end
|
502
504
|
|
503
|
-
unless default_attr_data.
|
505
|
+
unless default_attr_data.is_a?(Hash)
|
504
506
|
raise InvalidLockfile, "lockfile's `default_attributes` attribute must be a Hash (JSON object). (got: #{default_attr_data.inspect})"
|
505
507
|
end
|
506
508
|
|
@@ -510,7 +512,7 @@ module ChefCLI
|
|
510
512
|
raise InvalidLockfile, "lockfile does not have a `override_attributes` attribute"
|
511
513
|
end
|
512
514
|
|
513
|
-
unless override_attr_data.
|
515
|
+
unless override_attr_data.is_a?(Hash)
|
514
516
|
raise InvalidLockfile, "lockfile's `override_attributes` attribute must be a Hash (JSON object). (got: #{override_attr_data.inspect})"
|
515
517
|
end
|
516
518
|
|
@@ -525,7 +527,7 @@ module ChefCLI
|
|
525
527
|
raise InvalidLockfile, "lockfile does not have a solution_dependencies attribute"
|
526
528
|
end
|
527
529
|
|
528
|
-
unless soln_deps.
|
530
|
+
unless soln_deps.is_a?(Hash)
|
529
531
|
raise InvalidLockfile, "lockfile's solution_dependencies attribute must be a Hash (JSON object). (got: #{soln_deps.inspect})"
|
530
532
|
end
|
531
533
|
|
@@ -539,7 +541,7 @@ module ChefCLI
|
|
539
541
|
@included_policy_locks = []
|
540
542
|
else
|
541
543
|
locks.each do |lock_info|
|
542
|
-
|
544
|
+
unless %w{revision_id name source_options}.all? { |key| !lock_info[key].nil? }
|
543
545
|
raise InvalidLockfile, "lockfile included policy missing one of the required keys"
|
544
546
|
end
|
545
547
|
end
|
@@ -548,7 +550,7 @@ module ChefCLI
|
|
548
550
|
end
|
549
551
|
|
550
552
|
def build_cookbook_lock_from_lock_data(name, lock_info)
|
551
|
-
unless lock_info.
|
553
|
+
unless lock_info.is_a?(Hash)
|
552
554
|
raise InvalidLockfile, "lockfile cookbook_locks entries must be a Hash (JSON object). (got: #{lock_info.inspect})"
|
553
555
|
end
|
554
556
|
|
@@ -560,7 +562,7 @@ module ChefCLI
|
|
560
562
|
end
|
561
563
|
|
562
564
|
def build_cookbook_lock_as_archive_from_lock_data(name, lock_info)
|
563
|
-
unless lock_info.
|
565
|
+
unless lock_info.is_a?(Hash)
|
564
566
|
raise InvalidLockfile, "lockfile cookbook_locks entries must be a Hash (JSON object). (got: #{lock_info.inspect})"
|
565
567
|
end
|
566
568
|
|
@@ -45,7 +45,7 @@ module ChefCLI
|
|
45
45
|
[ remove_policy(policy), policy ]
|
46
46
|
end
|
47
47
|
|
48
|
-
failures = results.select { |result, _policy| result.
|
48
|
+
failures = results.select { |result, _policy| result.is_a?(Exception) }
|
49
49
|
|
50
50
|
unless failures.empty?
|
51
51
|
details = failures.map do |result, policy|
|
@@ -76,8 +76,8 @@ module ChefCLI
|
|
76
76
|
|
77
77
|
def http_client
|
78
78
|
@http_client ||= Chef::ServerAPI.new(chef_config.chef_server_url,
|
79
|
-
|
80
|
-
|
79
|
+
signing_key_filename: chef_config.client_key,
|
80
|
+
client_name: chef_config.node_name)
|
81
81
|
end
|
82
82
|
|
83
83
|
private
|
@@ -115,8 +115,8 @@ module ChefCLI
|
|
115
115
|
# server URL and credentials.
|
116
116
|
def http_client
|
117
117
|
@http_client ||= Chef::ServerAPI.new(chef_config.chef_server_url,
|
118
|
-
|
119
|
-
|
118
|
+
signing_key_filename: chef_config.client_key,
|
119
|
+
client_name: chef_config.node_name)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -90,6 +90,7 @@ module ChefCLI
|
|
90
90
|
|
91
91
|
def archive_file_location
|
92
92
|
return nil unless archive?
|
93
|
+
|
93
94
|
filename = "#{policyfile_lock.name}-#{policyfile_lock.revision_id}.tgz"
|
94
95
|
File.join(export_dir, filename)
|
95
96
|
end
|
@@ -158,7 +159,7 @@ module ChefCLI
|
|
158
159
|
dirname = "#{lock.name}-#{lock.identifier}"
|
159
160
|
export_path = File.join(staging_dir, "cookbook_artifacts", dirname)
|
160
161
|
metadata_rb_path = File.join(export_path, "metadata.rb")
|
161
|
-
FileUtils.mkdir(export_path)
|
162
|
+
FileUtils.mkdir(export_path) unless File.directory?(export_path)
|
162
163
|
copy_unignored_cookbook_files(lock, export_path)
|
163
164
|
FileUtils.rm_f(metadata_rb_path)
|
164
165
|
metadata = lock.cookbook_version.metadata
|
@@ -320,6 +321,7 @@ module ChefCLI
|
|
320
321
|
|
321
322
|
def validate_lockfile
|
322
323
|
return @policyfile_lock if @policyfile_lock
|
324
|
+
|
323
325
|
@policyfile_lock = ChefCLI::PolicyfileLock.new(storage_config).build_from_lock_data(policy_data)
|
324
326
|
# TODO: enumerate any cookbook that have been updated
|
325
327
|
@policyfile_lock.validate_cookbooks!
|
@@ -344,7 +346,7 @@ module ChefCLI
|
|
344
346
|
|
345
347
|
def assert_export_dir_clean!
|
346
348
|
if !force_export? && !conflicting_fs_entries.empty? && !archive?
|
347
|
-
msg = "Export dir (#{export_dir}) not clean. Refusing to export. (Conflicting files: #{conflicting_fs_entries.join(
|
349
|
+
msg = "Export dir (#{export_dir}) not clean. Refusing to export. (Conflicting files: #{conflicting_fs_entries.join(", ")})"
|
348
350
|
raise ExportDirNotEmpty, msg
|
349
351
|
end
|
350
352
|
end
|