chef 11.16.4-x86-mingw32 → 11.18.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -2
  3. data/lib/chef/api_client.rb +1 -1
  4. data/lib/chef/chef_fs/chef_fs_data_store.rb +3 -2
  5. data/lib/chef/chef_fs/command_line.rb +3 -2
  6. data/lib/chef/chef_fs/data_handler/group_data_handler.rb +5 -1
  7. data/lib/chef/chef_fs/file_system/acl_entry.rb +2 -1
  8. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +2 -1
  9. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +3 -2
  10. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +5 -4
  11. data/lib/chef/config_fetcher.rb +1 -1
  12. data/lib/chef/cookbook/cookbook_version_loader.rb +4 -4
  13. data/lib/chef/cookbook/metadata.rb +1 -1
  14. data/lib/chef/cookbook_version.rb +2 -2
  15. data/lib/chef/data_bag.rb +1 -1
  16. data/lib/chef/data_bag_item.rb +1 -1
  17. data/lib/chef/encrypted_data_bag_item/decryptor.rb +3 -3
  18. data/lib/chef/environment.rb +1 -1
  19. data/lib/chef/exceptions.rb +19 -2
  20. data/lib/chef/json_compat.rb +64 -45
  21. data/lib/chef/knife/bootstrap.rb +2 -2
  22. data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
  23. data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
  24. data/lib/chef/knife/bootstrap/chef-aix.erb +2 -2
  25. data/lib/chef/knife/bootstrap/chef-full.erb +2 -2
  26. data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
  27. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  28. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
  29. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  30. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  31. data/lib/chef/knife/cookbook_site_install.rb +34 -10
  32. data/lib/chef/knife/cookbook_site_list.rb +1 -1
  33. data/lib/chef/knife/cookbook_site_search.rb +1 -1
  34. data/lib/chef/knife/cookbook_site_share.rb +2 -2
  35. data/lib/chef/knife/cookbook_site_show.rb +3 -3
  36. data/lib/chef/knife/cookbook_site_unshare.rb +1 -1
  37. data/lib/chef/knife/core/subcommand_loader.rb +24 -0
  38. data/lib/chef/knife/deps.rb +3 -2
  39. data/lib/chef/node.rb +1 -1
  40. data/lib/chef/provider/deploy/revision.rb +1 -1
  41. data/lib/chef/provider/dsc_script.rb +32 -5
  42. data/lib/chef/provider/env.rb +25 -10
  43. data/lib/chef/provider/remote_file/cache_control_data.rb +1 -1
  44. data/lib/chef/resource.rb +1 -1
  45. data/lib/chef/resource/dsc_script.rb +2 -16
  46. data/lib/chef/resource_collection.rb +1 -1
  47. data/lib/chef/resource_reporter.rb +3 -3
  48. data/lib/chef/role.rb +1 -1
  49. data/lib/chef/run_list.rb +1 -1
  50. data/lib/chef/user.rb +1 -1
  51. data/lib/chef/util/dsc/local_configuration_manager.rb +15 -11
  52. data/lib/chef/util/powershell/cmdlet_result.rb +2 -2
  53. data/lib/chef/version.rb +1 -2
  54. data/spec/data/bootstrap/test-hints.erb +1 -1
  55. data/spec/data/bootstrap/test.erb +1 -1
  56. data/spec/functional/knife/cookbook_delete_spec.rb +3 -3
  57. data/spec/functional/knife/exec_spec.rb +1 -1
  58. data/spec/functional/resource/dsc_script_spec.rb +92 -47
  59. data/spec/functional/resource/env_spec.rb +3 -4
  60. data/spec/functional/util/powershell/cmdlet_spec.rb +1 -2
  61. data/spec/integration/knife/chef_fs_data_store_spec.rb +1 -1
  62. data/spec/integration/knife/chef_repo_path_spec.rb +6 -1
  63. data/spec/integration/knife/chef_repository_file_system_spec.rb +1 -1
  64. data/spec/integration/knife/chefignore_spec.rb +1 -1
  65. data/spec/integration/knife/common_options_spec.rb +1 -1
  66. data/spec/integration/knife/cookbook_api_ipv6_spec.rb +1 -1
  67. data/spec/integration/knife/delete_spec.rb +1 -1
  68. data/spec/integration/knife/deps_spec.rb +1 -1
  69. data/spec/integration/knife/diff_spec.rb +3 -3
  70. data/spec/integration/knife/download_spec.rb +3 -3
  71. data/spec/integration/knife/list_spec.rb +1 -1
  72. data/spec/integration/knife/raw_spec.rb +11 -1
  73. data/spec/integration/knife/redirection_spec.rb +1 -1
  74. data/spec/integration/knife/serve_spec.rb +1 -1
  75. data/spec/integration/knife/show_spec.rb +1 -1
  76. data/spec/integration/knife/upload_spec.rb +9 -9
  77. data/spec/spec_helper.rb +6 -0
  78. data/spec/support/shared/integration/integration_helper.rb +1 -2
  79. data/spec/support/shared/shared_examples.rb +10 -0
  80. data/spec/tiny_server.rb +2 -1
  81. data/spec/unit/api_client_spec.rb +3 -3
  82. data/spec/unit/chef_fs/data_handler/group_handler_spec.rb +63 -0
  83. data/spec/unit/config_fetcher_spec.rb +1 -1
  84. data/spec/unit/cookbook/metadata_spec.rb +7 -3
  85. data/spec/unit/cookbook_loader_spec.rb +1 -1
  86. data/spec/unit/cookbook_version_spec.rb +4 -0
  87. data/spec/unit/data_bag_item_spec.rb +5 -1
  88. data/spec/unit/data_bag_spec.rb +5 -1
  89. data/spec/unit/deprecation_spec.rb +1 -1
  90. data/spec/unit/encrypted_data_bag_item_spec.rb +14 -7
  91. data/spec/unit/environment_spec.rb +7 -3
  92. data/spec/unit/exceptions_spec.rb +6 -0
  93. data/spec/unit/json_compat_spec.rb +58 -17
  94. data/spec/unit/knife/cookbook_metadata_from_file_spec.rb +0 -1
  95. data/spec/unit/knife/cookbook_site_download_spec.rb +2 -1
  96. data/spec/unit/knife/cookbook_site_install_spec.rb +161 -116
  97. data/spec/unit/knife/cookbook_site_share_spec.rb +6 -6
  98. data/spec/unit/knife/core/bootstrap_context_spec.rb +2 -2
  99. data/spec/unit/knife/core/subcommand_loader_spec.rb +66 -1
  100. data/spec/unit/knife/data_bag_from_file_spec.rb +1 -2
  101. data/spec/unit/node_spec.rb +4 -0
  102. data/spec/unit/provider/dsc_script_spec.rb +134 -105
  103. data/spec/unit/provider/env/windows_spec.rb +2 -2
  104. data/spec/unit/provider/env_spec.rb +76 -11
  105. data/spec/unit/provider/remote_file/cache_control_data_spec.rb +1 -1
  106. data/spec/unit/resource/dsc_script_spec.rb +0 -29
  107. data/spec/unit/resource_collection_spec.rb +5 -1
  108. data/spec/unit/resource_reporter_spec.rb +3 -3
  109. data/spec/unit/resource_spec.rb +5 -1
  110. data/spec/unit/role_spec.rb +4 -0
  111. data/spec/unit/run_list_spec.rb +5 -1
  112. data/spec/unit/user_spec.rb +5 -1
  113. data/spec/unit/util/dsc/local_configuration_manager_spec.rb +15 -10
  114. metadata +11 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2163d53b7e3565637f8ab35c560b2e54bc017aeb
4
- data.tar.gz: e11a51630de5fcaf4fec98336cf0389b9aec096d
3
+ metadata.gz: c3615f31799357ca26ad8250694ce65c90f3970a
4
+ data.tar.gz: 8d487236c9c98c10a7e04b95a33dce3cad93e38e
5
5
  SHA512:
6
- metadata.gz: 4d972f1287a921d6fe4643484ef55df919de1d9274af50e812f403a05b389791bd94f1c171d625cdc14b28ccb33a7958a2d21ecb49c2c55321a2d2321f015aaa
7
- data.tar.gz: bf3698f0ca7c0e2d350a9c1ec3cd5ccaee2a608fe7025e946352838d7115b37b6e32c772209f86133c1ea6e68b75a4789d7b373a07b0229f58952fd8f9f0f813
6
+ metadata.gz: 406a6064e1d7272b54798729257ad17ccf831c44b5dd3be245a075df74e2d42327dd96b924bbe546054c3bba9db4d6632293f3440245cb1b86dff25af6375d93
7
+ data.tar.gz: 2d48535134666e13753b08eed5c91a1b29403d2f9dc3fd707e4f22d60875153843b05a5e3a292c05b10c8f94f6a6134eceae905251da7a076c2d7ed70e917e98
data/Rakefile CHANGED
@@ -41,8 +41,8 @@ end
41
41
 
42
42
  desc "Build it, tag it and ship it"
43
43
  task :ship => :gem do
44
- sh("git tag #{Chef::VERSION}")
45
- sh("git push opscode --tags")
44
+ #sh("git tag #{Chef::VERSION}")
45
+ #sh("git push opscode --tags")
46
46
  Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem|
47
47
  sh("gem push #{built_gem}")
48
48
  end
@@ -121,7 +121,7 @@ class Chef
121
121
  #
122
122
  # @return [String] the JSON string.
123
123
  def to_json(*a)
124
- to_hash.to_json(*a)
124
+ Chef::JSONCompat.to_json(to_hash, *a)
125
125
  end
126
126
 
127
127
  def self.json_create(o)
@@ -23,6 +23,7 @@ require 'chef/chef_fs/file_pattern'
23
23
  require 'chef/chef_fs/file_system'
24
24
  require 'chef/chef_fs/file_system/not_found_error'
25
25
  require 'chef/chef_fs/file_system/memory_root'
26
+ require 'chef/json_compat'
26
27
  require 'fileutils'
27
28
 
28
29
  class Chef
@@ -114,7 +115,7 @@ class Chef
114
115
  end
115
116
  end
116
117
  end
117
- JSON.pretty_generate(result)
118
+ Chef::JSONCompat.to_json_pretty(result)
118
119
 
119
120
  else
120
121
  begin
@@ -269,7 +270,7 @@ class Chef
269
270
 
270
271
  # Create a little Chef::ChefFS memory filesystem with the data
271
272
  cookbook_fs = Chef::ChefFS::FileSystem::MemoryRoot.new('uploading')
272
- cookbook = JSON.parse(data, :create_additions => false)
273
+ cookbook = Chef::JSONCompat.parse(data, :create_additions => false)
273
274
  cookbook.each_pair do |key, value|
274
275
  if value.is_a?(Array)
275
276
  value.each do |file|
@@ -19,6 +19,7 @@
19
19
  require 'chef/chef_fs/file_system'
20
20
  require 'chef/chef_fs/file_system/operation_failed_error'
21
21
  require 'chef/chef_fs/file_system/operation_not_allowed_error'
22
+ require 'chef/json_compat'
22
23
  require 'chef/util/diff'
23
24
 
24
25
  class Chef
@@ -251,9 +252,9 @@ class Chef
251
252
  end
252
253
 
253
254
  def self.canonicalize_json(json_text)
254
- parsed_json = JSON.parse(json_text, :create_additions => false)
255
+ parsed_json = Chef::JSONCompat.parse(json_text, :create_additions => false)
255
256
  sorted_json = sort_keys(parsed_json)
256
- JSON.pretty_generate(sorted_json)
257
+ Chef::JSONCompat.to_json_pretty(sorted_json)
257
258
  end
258
259
 
259
260
  def self.diff_text(old_path, new_path, old_value, new_value)
@@ -36,7 +36,11 @@ class Chef
36
36
  result
37
37
  end
38
38
 
39
- def preserve_key(key)
39
+ def normalize_for_post(group, entry)
40
+ normalize_for_put(group, entry)
41
+ end
42
+
43
+ def preserve_key?(key)
40
44
  return key == 'name'
41
45
  end
42
46
 
@@ -20,6 +20,7 @@ require 'chef/chef_fs/file_system/rest_list_entry'
20
20
  require 'chef/chef_fs/file_system/not_found_error'
21
21
  require 'chef/chef_fs/file_system/operation_not_allowed_error'
22
22
  require 'chef/chef_fs/file_system/operation_failed_error'
23
+ require 'chef/json_compat'
23
24
 
24
25
  class Chef
25
26
  module ChefFS
@@ -37,7 +38,7 @@ class Chef
37
38
 
38
39
  def write(file_contents)
39
40
  # ACL writes are fun.
40
- acls = data_handler.normalize(JSON.parse(file_contents, :create_additions => false), self)
41
+ acls = data_handler.normalize(Chef::JSONCompat.parse(file_contents, :create_additions => false), self)
41
42
  PERMISSIONS.each do |permission|
42
43
  begin
43
44
  rest.put("#{api_path}/#{permission}", { permission => acls[permission] })
@@ -19,6 +19,7 @@
19
19
 
20
20
  require 'chef/chef_fs/file_system/file_system_entry'
21
21
  require 'chef/chef_fs/file_system/not_found_error'
22
+ require 'chef/json_compat'
22
23
 
23
24
  class Chef
24
25
  module ChefFS
@@ -41,7 +42,7 @@ class Chef
41
42
 
42
43
  def chef_object
43
44
  begin
44
- return data_handler.chef_object(JSON.parse(read, :create_additions => false))
45
+ return data_handler.chef_object(Chef::JSONCompat.parse(read, :create_additions => false))
45
46
  rescue
46
47
  Chef::Log.error("Could not read #{path_for_printing} into a Chef object: #{$!}")
47
48
  end
@@ -19,6 +19,7 @@
19
19
  require 'chef/chef_fs/file_system/base_fs_dir'
20
20
  require 'chef/chef_fs/file_system/rest_list_entry'
21
21
  require 'chef/chef_fs/file_system/not_found_error'
22
+ require 'chef/json_compat'
22
23
 
23
24
  class Chef
24
25
  module ChefFS
@@ -61,8 +62,8 @@ class Chef
61
62
 
62
63
  def create_child(name, file_contents)
63
64
  begin
64
- object = JSON.parse(file_contents, :create_additions => false)
65
- rescue JSON::ParserError => e
65
+ object = Chef::JSONCompat.parse(file_contents, :create_additions => false)
66
+ rescue Chef::Exceptions::JSON::ParseError => e
66
67
  raise Chef::ChefFS::FileSystem::OperationFailedError.new(:create_child, self, e), "Parse error reading JSON creating child '#{name}': #{e}"
67
68
  end
68
69
 
@@ -19,6 +19,7 @@
19
19
  require 'chef/chef_fs/file_system/base_fs_object'
20
20
  require 'chef/chef_fs/file_system/not_found_error'
21
21
  require 'chef/chef_fs/file_system/operation_failed_error'
22
+ require 'chef/json_compat'
22
23
  require 'chef/role'
23
24
  require 'chef/node'
24
25
 
@@ -128,8 +129,8 @@ class Chef
128
129
  value = minimize_value(value)
129
130
  value_json = Chef::JSONCompat.to_json_pretty(value)
130
131
  begin
131
- other_value = JSON.parse(other_value_json, :create_additions => false)
132
- rescue JSON::ParserError => e
132
+ other_value = Chef::JSONCompat.parse(other_value_json, :create_additions => false)
133
+ rescue Chef::Exceptions::JSON::ParseError => e
133
134
  Chef::Log.warn("Parse error reading #{other.path_for_printing} as JSON: #{e}")
134
135
  return [ nil, value_json, other_value_json ]
135
136
  end
@@ -145,8 +146,8 @@ class Chef
145
146
 
146
147
  def write(file_contents)
147
148
  begin
148
- object = JSON.parse(file_contents, :create_additions => false)
149
- rescue JSON::ParserError => e
149
+ object = Chef::JSONCompat.parse(file_contents, :create_additions => false)
150
+ rescue Chef::Exceptions::JSON::ParseError => e
150
151
  raise Chef::ChefFS::FileSystem::OperationFailedError.new(:write, self, e), "Parse error reading JSON: #{e}"
151
152
  end
152
153
 
@@ -18,7 +18,7 @@ class Chef
18
18
  config_data = read_config
19
19
  begin
20
20
  Chef::JSONCompat.from_json(config_data)
21
- rescue FFI_Yajl::ParseError => error
21
+ rescue Chef::Exceptions::JSON::ParseError => error
22
22
  Chef::Application.fatal!("Could not parse the provided JSON file (#{config_location}): " + error.message, 2)
23
23
  end
24
24
  end
@@ -170,7 +170,7 @@ class Chef
170
170
  def apply_ruby_metadata(file)
171
171
  begin
172
172
  @metadata.from_file(file)
173
- rescue JSON::ParserError
173
+ rescue Chef::Exceptions::JSON::ParseError
174
174
  Chef::Log.error("Error evaluating metadata.rb for #@cookbook_name in " + file)
175
175
  raise
176
176
  end
@@ -179,7 +179,7 @@ class Chef
179
179
  def apply_json_metadata(file)
180
180
  begin
181
181
  @metadata.from_json(IO.read(file))
182
- rescue JSON::ParserError
182
+ rescue Chef::Exceptions::JSON::ParseError
183
183
  Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
184
184
  raise
185
185
  end
@@ -189,7 +189,7 @@ class Chef
189
189
  begin
190
190
  data = Chef::JSONCompat.from_json(IO.read(file), :create_additions => false)
191
191
  @metadata.from_hash(data['metadata'])
192
- rescue JSON::ParserError
192
+ rescue Chef::Exceptions::JSON::ParseError
193
193
  Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in " + file)
194
194
  raise
195
195
  end
@@ -200,7 +200,7 @@ class Chef
200
200
  begin
201
201
  data = Chef::JSONCompat.from_json(IO.read(uploaded_cookbook_version_file), :create_additions => false)
202
202
  @frozen = data['frozen?']
203
- rescue JSON::ParserError
203
+ rescue Chef::Exceptions::JSON::ParseError
204
204
  Chef::Log.error("Couldn't parse cookbook metadata JSON for #@cookbook_name in #{uploaded_cookbook_version_file}")
205
205
  raise
206
206
  end
@@ -441,7 +441,7 @@ class Chef
441
441
  end
442
442
 
443
443
  def to_json(*a)
444
- self.to_hash.to_json(*a)
444
+ Chef::JSONCompat.to_json(self.to_hash, *a)
445
445
  end
446
446
 
447
447
  def self.from_hash(o)
@@ -459,7 +459,7 @@ class Chef
459
459
  def to_json(*a)
460
460
  result = self.to_hash
461
461
  result['json_class'] = self.class.name
462
- result.to_json(*a)
462
+ Chef::JSONCompat.to_json(result, *a)
463
463
  end
464
464
 
465
465
  def self.json_create(o)
@@ -469,7 +469,7 @@ class Chef
469
469
  cookbook_version.manifest = o
470
470
 
471
471
  # We don't need the following step when we decide to stop supporting deprecated operators in the metadata (e.g. <<, >>)
472
- cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(cookbook_version.metadata.to_json)
472
+ cookbook_version.manifest["metadata"] = Chef::JSONCompat.from_json(Chef::JSONCompat.to_json(cookbook_version.metadata))
473
473
 
474
474
  cookbook_version.freeze_version if o["frozen?"]
475
475
  cookbook_version
@@ -63,7 +63,7 @@ class Chef
63
63
 
64
64
  # Serialize this object as a hash
65
65
  def to_json(*a)
66
- to_hash.to_json(*a)
66
+ Chef::JSONCompat.to_json(to_hash, *a)
67
67
  end
68
68
 
69
69
  def chef_server_rest
@@ -118,7 +118,7 @@ class Chef
118
118
  "data_bag" => self.data_bag,
119
119
  "raw_data" => self.raw_data
120
120
  }
121
- result.to_json(*a)
121
+ Chef::JSONCompat.to_json(result, *a)
122
122
  end
123
123
 
124
124
  def self.from_hash(h)
@@ -17,10 +17,10 @@
17
17
  #
18
18
 
19
19
  require 'yaml'
20
- require 'ffi_yajl'
21
20
  require 'openssl'
22
21
  require 'base64'
23
22
  require 'digest/sha2'
23
+ require 'chef/json_compat'
24
24
  require 'chef/encrypted_data_bag_item'
25
25
  require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format'
26
26
  require 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format'
@@ -121,8 +121,8 @@ class Chef::EncryptedDataBagItem
121
121
  end
122
122
 
123
123
  def for_decrypted_item
124
- FFI_Yajl::Parser.parse(decrypted_data)["json_wrapper"]
125
- rescue FFI_Yajl::ParseError
124
+ Chef::JSONCompat.parse(decrypted_data)["json_wrapper"]
125
+ rescue Chef::Exceptions::JSON::ParseError
126
126
  # convert to a DecryptionFailure error because the most likely scenario
127
127
  # here is that the decryption step was unsuccessful but returned bad
128
128
  # data rather than raising an error.
@@ -129,7 +129,7 @@ class Chef
129
129
  end
130
130
 
131
131
  def to_json(*a)
132
- to_hash.to_json(*a)
132
+ Chef::JSONCompat.to_json(to_hash, *a)
133
133
  end
134
134
 
135
135
  def update_from!(o)
@@ -134,6 +134,17 @@ class Chef
134
134
  # Version constraints are not allowed in chef-solo
135
135
  class IllegalVersionConstraint < NotImplementedError; end
136
136
 
137
+ class MetadataNotValid < StandardError; end
138
+ class MetadataNotFound < StandardError
139
+ attr_reader :install_path
140
+ attr_reader :cookbook_name
141
+ def initialize(install_path, cookbook_name)
142
+ @install_path = install_path
143
+ @cookbook_name = cookbook_name
144
+ super "No metadata.rb or metadata.json found for cookbook #{@cookbook_name} in #{@install_path}"
145
+ end
146
+ end
147
+
137
148
  # File operation attempted but no permissions to perform it
138
149
  class InsufficientPermissions < RuntimeError; end
139
150
 
@@ -267,7 +278,7 @@ class Chef
267
278
  "non_existent_cookbooks" => non_existent_cookbooks,
268
279
  "cookbooks_with_no_versions" => cookbooks_with_no_matching_versions
269
280
  }
270
- result.to_json(*a)
281
+ Chef::JSONCompat.to_json(result, *a)
271
282
  end
272
283
  end
273
284
 
@@ -302,7 +313,7 @@ class Chef
302
313
  "non_existent_cookbooks" => non_existent_cookbooks,
303
314
  "most_constrained_cookbooks" => most_constrained_cookbooks
304
315
  }
305
- result.to_json(*a)
316
+ Chef::JSONCompat.to_json(result, *a)
306
317
  end
307
318
  end
308
319
 
@@ -337,5 +348,11 @@ class Chef
337
348
  end
338
349
 
339
350
  class BadProxyURI < RuntimeError; end
351
+
352
+ # Raised by Chef::JSONCompat
353
+ class JSON
354
+ class EncodeError < RuntimeError; end
355
+ class ParseError < RuntimeError; end
356
+ end
340
357
  end
341
358
  end
@@ -18,7 +18,9 @@
18
18
  # Wrapper class for interacting with JSON.
19
19
 
20
20
  require 'ffi_yajl'
21
- require 'ffi_yajl/json_gem' # XXX: parts of chef require JSON gem's Hash#to_json monkeypatch
21
+ require 'chef/exceptions'
22
+ # We're requiring this to prevent breaking consumers using Hash.to_json
23
+ require 'json'
22
24
 
23
25
  class Chef
24
26
  class JSONCompat
@@ -40,15 +42,24 @@ class Chef
40
42
 
41
43
  class <<self
42
44
 
45
+ # API to use to avoid create_addtions
46
+ def parse(source, opts = {})
47
+ begin
48
+ FFI_Yajl::Parser.parse(source, opts)
49
+ rescue FFI_Yajl::ParseError => e
50
+ raise Chef::Exceptions::JSON::ParseError, e.message
51
+ end
52
+ end
53
+
43
54
  # Just call the JSON gem's parse method with a modified :max_nesting field
44
55
  def from_json(source, opts = {})
45
- obj = ::FFI_Yajl::Parser.parse(source)
56
+ obj = parse(source, opts)
46
57
 
47
58
  # JSON gem requires top level object to be a Hash or Array (otherwise
48
59
  # you get the "must contain two octets" error). Yajl doesn't impose the
49
60
  # same limitation. For compatibility, we re-impose this condition.
50
61
  unless obj.kind_of?(Hash) or obj.kind_of?(Array)
51
- raise JSON::ParserError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
62
+ raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
52
63
  end
53
64
 
54
65
  # The old default in the json gem (which we are mimicing because we
@@ -66,17 +77,17 @@ class Chef
66
77
  # to an instance of Chef classes if desired.
67
78
  def map_to_rb_obj(json_obj)
68
79
  case json_obj
69
- when Hash
70
- mapped_hash = map_hash_to_rb_obj(json_obj)
71
- if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
72
- class_to_inflate.json_create(mapped_hash)
80
+ when Hash
81
+ mapped_hash = map_hash_to_rb_obj(json_obj)
82
+ if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
83
+ class_to_inflate.json_create(mapped_hash)
84
+ else
85
+ mapped_hash
86
+ end
87
+ when Array
88
+ json_obj.map {|e| map_to_rb_obj(e) }
73
89
  else
74
- mapped_hash
75
- end
76
- when Array
77
- json_obj.map {|e| map_to_rb_obj(e) }
78
- else
79
- json_obj
90
+ json_obj
80
91
  end
81
92
  end
82
93
 
@@ -88,52 +99,60 @@ class Chef
88
99
  end
89
100
 
90
101
  def to_json(obj, opts = nil)
91
- obj.to_json(opts)
102
+ begin
103
+ FFI_Yajl::Encoder.encode(obj, opts)
104
+ rescue FFI_Yajl::EncodeError => e
105
+ raise Chef::Exceptions::JSON::EncodeError, e.message
106
+ end
92
107
  end
93
108
 
94
109
  def to_json_pretty(obj, opts = nil)
95
- ::JSON.pretty_generate(obj, opts)
110
+ opts ||= {}
111
+ options_map = {}
112
+ options_map[:pretty] = true
113
+ options_map[:indent] = opts[:indent] if opts.has_key?(:indent)
114
+ to_json(obj, options_map).chomp
96
115
  end
97
116
 
98
-
99
117
  # Map +json_class+ to a Class object. We use a +case+ instead of a Hash
100
118
  # assigned to a constant because otherwise this file could not be loaded
101
119
  # until all the constants were defined, which means you'd have to load
102
120
  # the world to get json, which would make knife very slow.
103
121
  def class_for_json_class(json_class)
104
122
  case json_class
105
- when CHEF_APICLIENT
106
- Chef::ApiClient
107
- when CHEF_CHECKSUM
108
- Chef::Checksum
109
- when CHEF_COOKBOOKVERSION
110
- Chef::CookbookVersion
111
- when CHEF_DATABAG
112
- Chef::DataBag
113
- when CHEF_DATABAGITEM
114
- Chef::DataBagItem
115
- when CHEF_ENVIRONMENT
116
- Chef::Environment
117
- when CHEF_NODE
118
- Chef::Node
119
- when CHEF_ROLE
120
- Chef::Role
121
- when CHEF_SANDBOX
122
- # a falsey return here will disable object inflation/"create
123
- # additions" in the caller. In Chef 11 this is correct, we just have
124
- # a dummy Chef::Sandbox class for compat with Chef 10 servers.
125
- false
126
- when CHEF_RESOURCE
127
- Chef::Resource
128
- when CHEF_RESOURCECOLLECTION
129
- Chef::ResourceCollection
130
- when /^Chef::Resource/
131
- Chef::Resource.find_subclass_by_name(json_class)
132
- else
133
- raise JSON::ParserError, "Unsupported `json_class` type '#{json_class}'"
123
+ when CHEF_APICLIENT
124
+ Chef::ApiClient
125
+ when CHEF_CHECKSUM
126
+ Chef::Checksum
127
+ when CHEF_COOKBOOKVERSION
128
+ Chef::CookbookVersion
129
+ when CHEF_DATABAG
130
+ Chef::DataBag
131
+ when CHEF_DATABAGITEM
132
+ Chef::DataBagItem
133
+ when CHEF_ENVIRONMENT
134
+ Chef::Environment
135
+ when CHEF_NODE
136
+ Chef::Node
137
+ when CHEF_ROLE
138
+ Chef::Role
139
+ when CHEF_SANDBOX
140
+ # a falsey return here will disable object inflation/"create
141
+ # additions" in the caller. In Chef 11 this is correct, we just have
142
+ # a dummy Chef::Sandbox class for compat with Chef 10 servers.
143
+ false
144
+ when CHEF_RESOURCE
145
+ Chef::Resource
146
+ when CHEF_RESOURCECOLLECTION
147
+ Chef::ResourceCollection
148
+ when /^Chef::Resource/
149
+ Chef::Resource.find_subclass_by_name(json_class)
150
+ else
151
+ raise Chef::Exceptions::JSON::ParseError, "Unsupported `json_class` type '#{json_class}'"
134
152
  end
135
153
  end
136
154
 
137
155
  end
138
156
  end
139
157
  end
158
+