summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@may.lt>2017-03-14 17:09:51 +0000
committerGitHub <noreply@github.com>2017-03-14 17:09:51 +0000
commit5f998d4e2b9d4c88bf1e58d1f1c19dc4d17ffeff (patch)
treee719e34d1185150eecfcc52c83364052d9652a8d
parent813117990834b2dbc53c7f81995670ac246a52c8 (diff)
parentb0cb79f89d7ed5efafd81e01d28dcce1014f41b3 (diff)
downloadchef-5f998d4e2b9d4c88bf1e58d1f1c19dc4d17ffeff.tar.gz
Merge pull request #5899 from chef/tm/remove_json_autoinflate
Kill JSON auto inflate with fire
-rw-r--r--lib/chef/api_client.rb5
-rw-r--r--lib/chef/cookbook_version.rb5
-rw-r--r--lib/chef/data_bag.rb6
-rw-r--r--lib/chef/data_bag_item.rb6
-rw-r--r--lib/chef/environment.rb5
-rw-r--r--lib/chef/json_compat.rb94
-rw-r--r--lib/chef/key.rb5
-rw-r--r--lib/chef/knife/core/ui.rb3
-rw-r--r--lib/chef/node.rb6
-rw-r--r--lib/chef/org.rb5
-rw-r--r--lib/chef/resource.rb11
-rw-r--r--lib/chef/resource_collection.rb10
-rw-r--r--lib/chef/resource_collection/resource_collection_serialization.rb9
-rw-r--r--lib/chef/resource_collection/resource_list.rb6
-rw-r--r--lib/chef/resource_collection/resource_set.rb8
-rw-r--r--lib/chef/role.rb6
-rw-r--r--lib/chef/user.rb5
-rw-r--r--lib/chef/user_v1.rb5
-rw-r--r--spec/unit/json_compat_spec.rb32
-rw-r--r--spec/unit/knife/core/ui_spec.rb29
-rw-r--r--spec/unit/resource_collection_spec.rb4
-rw-r--r--spec/unit/resource_spec.rb2
22 files changed, 67 insertions, 200 deletions
diff --git a/lib/chef/api_client.rb b/lib/chef/api_client.rb
index 6999a4f52d..087de3fdf9 100644
--- a/lib/chef/api_client.rb
+++ b/lib/chef/api_client.rb
@@ -140,11 +140,6 @@ class Chef
client
end
- def self.json_create(data)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::ApiClient#from_hash")
- from_hash(data)
- end
-
def self.from_json(j)
from_hash(Chef::JSONCompat.parse(j))
end
diff --git a/lib/chef/cookbook_version.rb b/lib/chef/cookbook_version.rb
index 2037b5f972..7353941bb1 100644
--- a/lib/chef/cookbook_version.rb
+++ b/lib/chef/cookbook_version.rb
@@ -484,11 +484,6 @@ class Chef
cookbook_version
end
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::CookbookVersion#from_hash")
- from_hash(o)
- end
-
def self.from_cb_artifact_data(o)
from_hash(o)
end
diff --git a/lib/chef/data_bag.rb b/lib/chef/data_bag.rb
index 4bb656a2c8..15531d7304 100644
--- a/lib/chef/data_bag.rb
+++ b/lib/chef/data_bag.rb
@@ -78,12 +78,6 @@ class Chef
Chef::ServerAPI.new(Chef::Config[:chef_server_url])
end
- # Create a Chef::Role from JSON
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::DataBag#from_hash")
- from_hash(o)
- end
-
def self.from_hash(o)
bag = new
bag.name(o["name"])
diff --git a/lib/chef/data_bag_item.rb b/lib/chef/data_bag_item.rb
index 2bd27e3eef..ddb520dc0b 100644
--- a/lib/chef/data_bag_item.rb
+++ b/lib/chef/data_bag_item.rb
@@ -139,12 +139,6 @@ class Chef
item
end
- # Create a Chef::DataBagItem from JSON
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::DataBagItem#from_hash")
- from_hash(o)
- end
-
# Load a Data Bag Item by name via either the RESTful API or local data_bag_path if run in solo mode
def self.load(data_bag, name)
if Chef::Config[:solo_legacy_mode]
diff --git a/lib/chef/environment.rb b/lib/chef/environment.rb
index 545a2e51eb..621a122440 100644
--- a/lib/chef/environment.rb
+++ b/lib/chef/environment.rb
@@ -216,11 +216,6 @@ class Chef
end
end
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Environment#from_hash")
- from_hash(o)
- end
-
def self.from_hash(o)
environment = new
environment.name(o["name"])
diff --git a/lib/chef/json_compat.rb b/lib/chef/json_compat.rb
index c8f5496345..b819d5e57d 100644
--- a/lib/chef/json_compat.rb
+++ b/lib/chef/json_compat.rb
@@ -26,23 +26,6 @@ class Chef
class JSONCompat
JSON_MAX_NESTING = 1000
- JSON_CLASS = "json_class".freeze
-
- CHEF_APICLIENT = "Chef::ApiClient".freeze
- CHEF_CHECKSUM = "Chef::Checksum".freeze
- CHEF_COOKBOOKVERSION = "Chef::CookbookVersion".freeze
- CHEF_DATABAG = "Chef::DataBag".freeze
- CHEF_DATABAGITEM = "Chef::DataBagItem".freeze
- CHEF_ENVIRONMENT = "Chef::Environment".freeze
- CHEF_NODE = "Chef::Node".freeze
- CHEF_ROLE = "Chef::Role".freeze
- CHEF_SANDBOX = "Chef::Sandbox".freeze
- CHEF_RESOURCE = "Chef::Resource".freeze
- CHEF_RESOURCECOLLECTION = "Chef::ResourceCollection".freeze
- CHEF_RESOURCESET = "Chef::ResourceCollection::ResourceSet".freeze
- CHEF_RESOURCELIST = "Chef::ResourceCollection::ResourceList".freeze
- CHEF_RUNLISTEXPANSION = "Chef::RunListExpansion".freeze
-
class <<self
# API to use to avoid create_addtions
@@ -63,40 +46,7 @@ class Chef
raise Chef::Exceptions::JSON::ParseError, "Top level JSON object must be a Hash or Array. (actual: #{obj.class})"
end
- # The old default in the json gem (which we are mimicing because we
- # sadly rely on this misfeature) is to "create additions" i.e., convert
- # JSON objects into ruby objects. Explicit :create_additions => false
- # is required to turn it off.
- if opts[:create_additions].nil? || opts[:create_additions]
- map_to_rb_obj(obj)
- else
- obj
- end
- end
-
- # Look at an object that's a basic type (from json parse) and convert it
- # to an instance of Chef classes if desired.
- def map_to_rb_obj(json_obj)
- case json_obj
- when Hash
- mapped_hash = map_hash_to_rb_obj(json_obj)
- if json_obj.has_key?(JSON_CLASS) && (class_to_inflate = class_for_json_class(json_obj[JSON_CLASS]))
- class_to_inflate.json_create(mapped_hash)
- else
- mapped_hash
- end
- when Array
- json_obj.map { |e| map_to_rb_obj(e) }
- else
- json_obj
- end
- end
-
- def map_hash_to_rb_obj(json_hash)
- json_hash.each do |key, value|
- json_hash[key] = map_to_rb_obj(value)
- end
- json_hash
+ obj
end
def to_json(obj, opts = nil)
@@ -113,48 +63,6 @@ class Chef
to_json(obj, options_map).chomp
end
- # Map +json_class+ to a Class object. We use a +case+ instead of a Hash
- # assigned to a constant because otherwise this file could not be loaded
- # until all the constants were defined, which means you'd have to load
- # the world to get json, which would make knife very slow.
- def class_for_json_class(json_class)
- case json_class
- when CHEF_APICLIENT
- Chef::ApiClient
- when CHEF_CHECKSUM
- Chef::Checksum
- when CHEF_COOKBOOKVERSION
- Chef::CookbookVersion
- when CHEF_DATABAG
- Chef::DataBag
- when CHEF_DATABAGITEM
- Chef::DataBagItem
- when CHEF_ENVIRONMENT
- Chef::Environment
- when CHEF_NODE
- Chef::Node
- when CHEF_ROLE
- Chef::Role
- when CHEF_SANDBOX
- # a falsey return here will disable object inflation/"create
- # additions" in the caller. In Chef 11 this is correct, we just have
- # a dummy Chef::Sandbox class for compat with Chef 10 servers.
- false
- when CHEF_RESOURCE
- Chef::Resource
- when CHEF_RESOURCECOLLECTION
- Chef::ResourceCollection
- when CHEF_RESOURCESET
- Chef::ResourceCollection::ResourceSet
- when CHEF_RESOURCELIST
- Chef::ResourceCollection::ResourceList
- when /^Chef::Resource/
- Chef::Resource.find_descendants_by_name(json_class)
- else
- raise Chef::Exceptions::JSON::ParseError, "Unsupported `json_class` type '#{json_class}'"
- end
- end
-
end
end
end
diff --git a/lib/chef/key.rb b/lib/chef/key.rb
index c68fe1039c..bf8e533d62 100644
--- a/lib/chef/key.rb
+++ b/lib/chef/key.rb
@@ -222,11 +222,6 @@ class Chef
Chef::Key.from_hash(Chef::JSONCompat.from_json(json))
end
- def json_create(json)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Key#from_json or one of the load_by methods.")
- Chef::Key.from_json(json)
- end
-
def list_by_user(actor, inflate = false)
keys = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("users/#{actor}/keys")
list(keys, actor, :load_by_user, inflate)
diff --git a/lib/chef/knife/core/ui.rb b/lib/chef/knife/core/ui.rb
index 1fc6d3d0e2..d809a8fc45 100644
--- a/lib/chef/knife/core/ui.rb
+++ b/lib/chef/knife/core/ui.rb
@@ -180,8 +180,7 @@ class Chef
if parse_output
if object_class.nil?
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please pass in the class to inflate or use #edit_hash")
- Chef::JSONCompat.from_json(output)
+ raise ArgumentError, "Please pass in the object class to hydrate or use #edit_hash"
else
object_class.from_hash(Chef::JSONCompat.parse(output))
end
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 1c2fbfee0f..92bdb5887b 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -508,12 +508,6 @@ class Chef
self
end
- # Create a Chef::Node from JSON
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Node#from_hash")
- from_hash(o)
- end
-
def self.from_hash(o)
return o if o.kind_of? Chef::Node
node = new
diff --git a/lib/chef/org.rb b/lib/chef/org.rb
index bed5600920..73a129c7c1 100644
--- a/lib/chef/org.rb
+++ b/lib/chef/org.rb
@@ -122,11 +122,6 @@ class Chef
Chef::Org.from_hash(Chef::JSONCompat.from_json(json))
end
- def self.json_create(json)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Org#from_json or Chef::Org#load.")
- Chef::Org.from_json(json)
- end
-
def self.load(org_name)
response = Chef::ServerAPI.new(Chef::Config[:chef_server_root]).get("organizations/#{org_name}")
Chef::Org.from_hash(response)
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 23de50324c..f8cea08076 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -23,6 +23,7 @@ require "chef/dsl/data_query"
require "chef/dsl/registry_helper"
require "chef/dsl/reboot_pending"
require "chef/dsl/resources"
+require "chef/json_compat"
require "chef/mixin/convert_to_class_name"
require "chef/guard_interpreter/resource_guard_interpreter"
require "chef/resource/conditional"
@@ -715,7 +716,7 @@ class Chef
result
end
- def self.json_create(o)
+ def self.from_hash(o)
resource = new(o["instance_vars"]["@name"])
o["instance_vars"].each do |k, v|
resource.instance_variable_set("@#{k}".to_sym, v)
@@ -723,6 +724,14 @@ class Chef
resource
end
+ def self.json_create(o)
+ from_hash(o)
+ end
+
+ def self.from_json(j)
+ from_hash(Chef::JSONCompat.parse(j))
+ end
+
#
# Resource Definition Interface (for resource developers)
#
diff --git a/lib/chef/resource_collection.rb b/lib/chef/resource_collection.rb
index 8eaa2961c4..e450f4f19e 100644
--- a/lib/chef/resource_collection.rb
+++ b/lib/chef/resource_collection.rb
@@ -117,6 +117,16 @@ class Chef
end
end
+ def self.from_hash(o)
+ collection = new()
+ { "@resource_list" => "ResourceList", "@resource_set" => "ResourceSet" }.each_pair do |name, klass|
+ obj = Chef::ResourceCollection.const_get(klass).from_hash(o["instance_vars"].delete(name))
+ collection.instance_variable_set(name.to_sym, obj)
+ end
+ collection.instance_variable_set(:@run_context, o["instance_vars"].delete("@run_context"))
+ collection
+ end
+
private
def lookup_recursive(rc, key)
diff --git a/lib/chef/resource_collection/resource_collection_serialization.rb b/lib/chef/resource_collection/resource_collection_serialization.rb
index 647d28dfd0..4da1ad5048 100644
--- a/lib/chef/resource_collection/resource_collection_serialization.rb
+++ b/lib/chef/resource_collection/resource_collection_serialization.rb
@@ -15,6 +15,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+
+require "chef/json_compat"
+
class Chef
class ResourceCollection
module ResourceCollectionSerialization
@@ -39,13 +42,17 @@ class Chef
end
module ClassMethods
- def json_create(o)
+ def from_hash(o)
collection = new()
o["instance_vars"].each do |k, v|
collection.instance_variable_set(k.to_sym, v)
end
collection
end
+
+ def from_json(j)
+ from_hash(Chef::JSONCompat.parse(j))
+ end
end
def is_chef_resource!(arg)
diff --git a/lib/chef/resource_collection/resource_list.rb b/lib/chef/resource_collection/resource_list.rb
index 9fe012d4c3..75305f63a6 100644
--- a/lib/chef/resource_collection/resource_list.rb
+++ b/lib/chef/resource_collection/resource_list.rb
@@ -95,6 +95,12 @@ class Chef
end
end
+ def self.from_hash(o)
+ collection = new()
+ resources = o["instance_vars"]["@resources"].map { |r| Chef::Resource.from_hash(r) }
+ collection.instance_variable_set(:@resources, resources)
+ collection
+ end
end
end
end
diff --git a/lib/chef/resource_collection/resource_set.rb b/lib/chef/resource_collection/resource_set.rb
index 1a73818790..2c7c0a0b91 100644
--- a/lib/chef/resource_collection/resource_set.rb
+++ b/lib/chef/resource_collection/resource_set.rb
@@ -132,6 +132,14 @@ class Chef
end
end
+ def self.from_hash(o)
+ collection = new()
+ rl = o["instance_vars"]["@resources_by_key"]
+ resources = rl.merge(rl) { |k, r| Chef::Resource.from_hash(r) }
+ collection.instance_variable_set(:@resources_by_key, resources)
+ collection
+ end
+
private
def create_key(resource_type, instance_name)
diff --git a/lib/chef/role.rb b/lib/chef/role.rb
index 218894ef03..c22c77b70d 100644
--- a/lib/chef/role.rb
+++ b/lib/chef/role.rb
@@ -168,12 +168,6 @@ class Chef
self
end
- # Create a Chef::Role from JSON
- def self.json_create(o)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::Role#from_hash")
- from_hash(o)
- end
-
def self.from_hash(o)
role = new
role.name(o["name"])
diff --git a/lib/chef/user.rb b/lib/chef/user.rb
index fffaa106f8..f52d0e2555 100644
--- a/lib/chef/user.rb
+++ b/lib/chef/user.rb
@@ -152,11 +152,6 @@ class Chef
Chef::User.from_hash(Chef::JSONCompat.from_json(json))
end
- def self.json_create(json)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::User#from_json or Chef::User#load.")
- Chef::User.from_json(json)
- end
-
def self.list(inflate = false)
response = Chef::ServerAPI.new(Chef::Config[:chef_server_url], { :api_version => "0" }).get("users")
users = if response.is_a?(Array)
diff --git a/lib/chef/user_v1.rb b/lib/chef/user_v1.rb
index b408bbe667..0ca17c6ed6 100644
--- a/lib/chef/user_v1.rb
+++ b/lib/chef/user_v1.rb
@@ -274,11 +274,6 @@ class Chef
Chef::UserV1.from_hash(Chef::JSONCompat.from_json(json))
end
- def self.json_create(json)
- Chef.deprecated(:json_auto_inflate, "Auto inflation of JSON data is deprecated. Please use Chef::UserV1#from_json or Chef::UserV1#load.")
- Chef::UserV1.from_json(json)
- end
-
def self.list(inflate = false)
response = Chef::ServerAPI.new(Chef::Config[:chef_server_url]).get("users")
users = if response.is_a?(Array)
diff --git a/spec/unit/json_compat_spec.rb b/spec/unit/json_compat_spec.rb
index 4da29fe4ec..38c2c60b2e 100644
--- a/spec/unit/json_compat_spec.rb
+++ b/spec/unit/json_compat_spec.rb
@@ -22,28 +22,6 @@ require "chef/json_compat"
describe Chef::JSONCompat do
before { Chef::Config[:treat_deprecation_warnings_as_errors] = false }
- describe "#from_json with JSON containing an existing class" do
- let(:json) { '{"json_class": "Chef::Role"}' }
-
- it "emits a deprecation warning" do
- Chef::Config[:treat_deprecation_warnings_as_errors] = true
- expect { Chef::JSONCompat.from_json(json) }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
- /Auto inflation of JSON data is deprecated. Please use Chef::Role#from_hash/
- end
-
- it "returns an instance of the class instead of a Hash" do
- expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
- end
- end
-
- describe "#from_json with JSON containing comments" do
- let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
-
- it "returns an instance of the class instead of a Hash" do
- expect(Chef::JSONCompat.from_json(json).class).to eq Chef::Role
- end
- end
-
describe "#parse with JSON containing comments" do
let(:json) { %Q{{\n/* comment */\n// comment 2\n"json_class": "Chef::Role"}} }
@@ -52,16 +30,6 @@ describe Chef::JSONCompat do
end
end
- describe 'with JSON containing "Chef::Sandbox" as a json_class value' do
- require "chef/sandbox" # Only needed for this test
-
- let(:json) { '{"json_class": "Chef::Sandbox", "arbitrary": "data"}' }
-
- it "returns a Hash, because Chef::Sandbox is a dummy class" do
- expect(Chef::JSONCompat.from_json(json)).to eq({ "json_class" => "Chef::Sandbox", "arbitrary" => "data" })
- end
- end
-
describe "when pretty printing an object that defines #to_json" do
class Foo
def to_json(*a)
diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb
index 38c72161e5..38614f44d9 100644
--- a/spec/unit/knife/core/ui_spec.rb
+++ b/spec/unit/knife/core/ui_spec.rb
@@ -34,16 +34,24 @@ describe Chef::Knife::UI do
Chef::Config[:treat_deprecation_warnings_as_errors] = false
end
+ class TestObject < OpenStruct
+ def self.from_hash(hsh)
+ new(hsh)
+ end
+ end
+
describe "edit" do
ruby_for_json = { "foo" => "bar" }
+ ruby_from_json = TestObject.from_hash(ruby_for_json)
json_from_ruby = "{\n \"foo\": \"bar\"\n}"
json_from_editor = "{\n \"bar\": \"foo\"\n}"
- ruby_from_editor = { "bar" => "foo" }
+ ruby_from_editor = TestObject.from_hash({ "bar" => "foo" })
my_editor = "veeeye"
temp_path = "/tmp/bar/baz"
- let(:subject) { @ui.edit_data(ruby_for_json, parse_output) }
+ let(:subject) { @ui.edit_data(ruby_for_json, parse_output, object_class: klass) }
let(:parse_output) { false }
+ let(:klass) { nil }
context "when editing is disabled" do
before do
@@ -57,17 +65,18 @@ describe Chef::Knife::UI do
end
context "when parse_output is true" do
let(:parse_output) { true }
+ let(:klass) { TestObject }
it "returns a ruby object" do
- expect(subject).to eql(ruby_for_json)
+ expect(subject).to eql(ruby_from_json)
end
-
- it "gives a deprecation error" do
- Chef::Config[:treat_deprecation_warnings_as_errors] = true
- expect { subject }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
- /Auto inflation of JSON data is deprecated./
+ context "but no object class is provided" do
+ let(:klass) { nil }
+ it "raises an error" do
+ expect { subject }.to raise_error ArgumentError,
+ /Please pass in the object class to hydrate or use #edit_hash/
+ end
end
end
-
end
context "when editing is enabled" do
@@ -94,6 +103,7 @@ describe Chef::Knife::UI do
end
context "when parse_output is true" do
let(:parse_output) { true }
+ let(:klass) { TestObject }
it "returns an edited ruby object" do
expect(subject).to eql(ruby_from_editor)
end
@@ -145,6 +155,7 @@ describe Chef::Knife::UI do
context "when parse_output is true" do
let(:parse_output) { true }
+ let(:klass) { TestObject }
it "returns an edited ruby object" do
expect(subject).to eql(ruby_from_editor)
end
diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb
index 5feb34833a..76038e51b9 100644
--- a/spec/unit/resource_collection_spec.rb
+++ b/spec/unit/resource_collection_spec.rb
@@ -291,10 +291,10 @@ describe Chef::ResourceCollection do
expect(rc.respond_to?(:from_json)).to eq(false)
end
- it "should convert from json using the CHEF::JSONCompat library" do
+ it "should convert from json using the Chef::JSONCompat library" do
rc << resource
json = Chef::JSONCompat.to_json(rc)
- s_rc = Chef::JSONCompat.from_json(json)
+ s_rc = Chef::ResourceCollection.from_json(json)
expect(s_rc).to be_a_kind_of(Chef::ResourceCollection)
expect(s_rc[0].name).to eql(resource.name)
end
diff --git a/spec/unit/resource_spec.rb b/spec/unit/resource_spec.rb
index df8ae3100a..c1aeb256fa 100644
--- a/spec/unit/resource_spec.rb
+++ b/spec/unit/resource_spec.rb
@@ -484,7 +484,7 @@ describe Chef::Resource do
describe "self.json_create" do
it "should deserialize itself from json" do
json = Chef::JSONCompat.to_json(resource)
- serialized_node = Chef::JSONCompat.from_json(json)
+ serialized_node = Chef::Resource.from_json(json)
expect(serialized_node).to be_a_kind_of(Chef::Resource)
expect(serialized_node.name).to eql(resource.name)
end